From b3fd50749de4db16b884aa279ed716615f16eb3b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sep 03 2008 23:41:17 +0000 Subject: xserver 1.5.0. --- diff --git a/.cvsignore b/.cvsignore index 5f54598..362bd81 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -xorg-server-20080701.tar.bz2 +xorg-server-1.5.0.tar.bz2 diff --git a/commitid b/commitid deleted file mode 100644 index 3388349..0000000 --- a/commitid +++ /dev/null @@ -1 +0,0 @@ -53a84d75c65f75c629c6610a2ec4093507cea3f7 diff --git a/gitignore b/gitignore new file mode 100644 index 0000000..524cfc6 --- /dev/null +++ b/gitignore @@ -0,0 +1,306 @@ +Makefile +Makefile.in +.deps +.libs +.msg +*.lo +*.la +*.a +*.o +*~ +.*sw? +*.pbxuser +*.mode1v3 +obj* +build* +local +aclocal.m4 +autom4te.cache +compile +config.guess +config.log +config.status +config.sub +configure +configure.lineno +depcomp +install-sh +libtool +ltmain.sh +missing +TAGS +tags +ylwrap +xorg-server.pc +stamp-h? +do-not-use-config.h +do-not-use-config.h.in +afb/afbbltC.c +afb/afbbltCI.c +afb/afbbltG.c +afb/afbbltO.c +afb/afbbltX.c +afb/afbseg.c +afb/afbtileC.c +afb/afbtileG.c +cfb/cfb8lineCO.c +cfb/cfb8lineCP.c +cfb/cfb8lineG.c +cfb/cfb8lineX.c +cfb/cfb8segC.c +cfb/cfb8segCS.c +cfb/cfb8segX.c +cfb/cfb8setG.c +cfb/cfbbltC.c +cfb/cfbbltG.c +cfb/cfbbltO.c +cfb/cfbbltX.c +cfb/cfbfillarcC.c +cfb/cfbfillarcG.c +cfb/cfbglrop8.c +cfb/cfbply1rctC.c +cfb/cfbply1rctG.c +cfb/cfbseg.c +cfb/cfbsolidC.c +cfb/cfbsolidG.c +cfb/cfbsolidX.c +cfb/cfbtile32C.c +cfb/cfbtile32G.c +cfb/cfbtileoddC.c +cfb/cfbtileoddG.c +cfb/cfbzerarcC.c +cfb/cfbzerarcG.c +cfb/cfbzerarcX.c +cfb32/cfb8lineCO.c +cfb32/cfb8lineCP.c +cfb32/cfb8lineG.c +cfb32/cfb8lineX.c +cfb32/cfb8segC.c +cfb32/cfb8segCS.c +cfb32/cfb8segX.c +cfb32/cfb8setG.c +cfb32/cfbbltC.c +cfb32/cfbbltG.c +cfb32/cfbbltO.c +cfb32/cfbbltX.c +cfb32/cfbfillarcC.c +cfb32/cfbfillarcG.c +cfb32/cfbply1rctC.c +cfb32/cfbply1rctG.c +cfb32/cfbseg.c +cfb32/cfbsolidC.c +cfb32/cfbsolidG.c +cfb32/cfbsolidX.c +cfb32/cfbtile32C.c +cfb32/cfbtile32G.c +cfb32/cfbtileoddC.c +cfb32/cfbtileoddG.c +cfb32/cfbzerarcC.c +cfb32/cfbzerarcG.c +cfb32/cfbzerarcX.c +doc/Xserver.1x +doc/Xserver.man +hw/dmx/Xdmx +hw/dmx/Xdmx.1x +hw/dmx/config/dmxtodmx +hw/dmx/config/dmxtodmx.1x +hw/dmx/config/parser.c +hw/dmx/config/parser.h +hw/dmx/config/scanner.c +hw/dmx/config/vdltodmx +hw/dmx/config/vdltodmx.1x +hw/dmx/config/xdmxconfig +hw/dmx/config/xdmxconfig.1x +hw/dmx/examples/dmxaddinput +hw/dmx/examples/dmxaddscreen +hw/dmx/examples/dmxreconfig +hw/dmx/examples/dmxresize +hw/dmx/examples/dmxrminput +hw/dmx/examples/dmxrmscreen +hw/dmx/examples/dmxwininfo +hw/dmx/examples/ev +hw/dmx/examples/evi +hw/dmx/examples/res +hw/dmx/examples/xbell +hw/dmx/examples/xdmx +hw/dmx/examples/xinput +hw/dmx/examples/xled +hw/dmx/examples/xtest +hw/kdrive/ati/Xati +hw/kdrive/chips/Xchips +hw/kdrive/ephyr/Xephyr +hw/kdrive/epson/Xepson +hw/kdrive/fake/Xfake +hw/kdrive/fbdev/Xfbdev +hw/kdrive/i810/Xi810 +hw/kdrive/mach64/Xmach64 +hw/kdrive/mga/Xmga +hw/kdrive/neomagic/Xneomagic +hw/kdrive/nvidia/Xnvidia +hw/kdrive/pm2/Xpm2 +hw/kdrive/r128/Xr128 +hw/kdrive/sdl/Xsdl +hw/kdrive/sis300/Xsis +hw/kdrive/smi/Xsmi +hw/kdrive/vesa/Xvesa +hw/kdrive/via/Xvia +hw/vfb/Xvfb +hw/vfb/Xvfb.1x +hw/vfb/Xvfb.man +hw/xfree86/Xorg +hw/xfree86/common/xf86Build.h +hw/xfree86/common/xf86DefModeSet.c +hw/xfree86/doc/man/Xorg.1x +hw/xfree86/doc/man/Xorg.man +hw/xfree86/doc/man/xorg.conf.5x +hw/xfree86/doc/man/xorg.conf.man +hw/xfree86/exa/exa.4 +hw/xfree86/exa/exa.4x +hw/xfree86/exa/exa.man +hw/xfree86/fbdevhw/fbdevhw.4x +hw/xfree86/fbdevhw/fbdevhw.man +hw/xfree86/getconfig/cfg.man +hw/xfree86/getconfig/getconfig.1x +hw/xfree86/getconfig/getconfig.5x +hw/xfree86/getconfig/getconfig.man +hw/xfree86/os-support/xorgos.c +hw/xfree86/osandcommon.c +hw/xfree86/ramdac/xf86BitOrder.c +hw/xfree86/scanpci/xf86PciData.c +hw/xfree86/scanpci/xf86PciIds.h +hw/xfree86/utils/cvt/cvt +hw/xfree86/utils/cvt/cvt.man +hw/xfree86/utils/gtf/gtf +hw/xfree86/utils/gtf/gtf.1x +hw/xfree86/utils/gtf/gtf.man +hw/xfree86/utils/ioport/inb +hw/xfree86/utils/ioport/inl +hw/xfree86/utils/ioport/inw +hw/xfree86/utils/ioport/ioport +hw/xfree86/utils/ioport/outb +hw/xfree86/utils/ioport/outl +hw/xfree86/utils/ioport/outw +hw/xfree86/utils/pcitweak/pcitweak +hw/xfree86/utils/pcitweak/pcitweak.1x +hw/xfree86/utils/pcitweak/pcitweak.man +hw/xfree86/utils/scanpci/scanpci +hw/xfree86/utils/scanpci/scanpci.1x +hw/xfree86/utils/scanpci/scanpci.man +hw/xfree86/utils/xorgcfg/XOrgCfg +hw/xfree86/utils/xorgcfg/xorgcfg +hw/xfree86/utils/xorgcfg/xorgcfg.1x +hw/xfree86/utils/xorgcfg/xorgcfg.man +hw/xfree86/utils/xorgconfig/xorgconfig +hw/xfree86/utils/xorgconfig/xorgconfig.1x +hw/xfree86/utils/xorgconfig/xorgconfig.man +hw/xfree86/xaa/l-xaaBitmap.c +hw/xfree86/xaa/l-xaaStipple.c +hw/xfree86/xaa/l-xaaTEGlyph.c +hw/xfree86/xaa/l3-xaaBitmap.c +hw/xfree86/xaa/l3-xaaStipple.c +hw/xfree86/xaa/lf-xaaBitmap.c +hw/xfree86/xaa/lf-xaaStipple.c +hw/xfree86/xaa/lf-xaaTEGlyph.c +hw/xfree86/xaa/lf3-xaaBitmap.c +hw/xfree86/xaa/lf3-xaaStipple.c +hw/xfree86/xaa/m-xaaBitmap.c +hw/xfree86/xaa/m-xaaStipple.c +hw/xfree86/xaa/m-xaaTEGlyph.c +hw/xfree86/xaa/m3-xaaBitmap.c +hw/xfree86/xaa/m3-xaaStipple.c +hw/xfree86/xaa/mf-xaaBitmap.c +hw/xfree86/xaa/mf-xaaStipple.c +hw/xfree86/xaa/mf-xaaTEGlyph.c +hw/xfree86/xaa/mf3-xaaBitmap.c +hw/xfree86/xaa/mf3-xaaStipple.c +hw/xfree86/xaa/s-xaaDashLine.c +hw/xfree86/xaa/s-xaaLine.c +hw/xfree86/xf1bpp/maskbits.c +hw/xfree86/xf1bpp/mfbbitblt.c +hw/xfree86/xf1bpp/mfbbltC.c +hw/xfree86/xf1bpp/mfbbltCI.c +hw/xfree86/xf1bpp/mfbbltG.c +hw/xfree86/xf1bpp/mfbbltO.c +hw/xfree86/xf1bpp/mfbbltX.c +hw/xfree86/xf1bpp/mfbbres.c +hw/xfree86/xf1bpp/mfbbresd.c +hw/xfree86/xf1bpp/mfbclip.c +hw/xfree86/xf1bpp/mfbcmap.c +hw/xfree86/xf1bpp/mfbfillarc.c +hw/xfree86/xf1bpp/mfbfillrct.c +hw/xfree86/xf1bpp/mfbfillsp.c +hw/xfree86/xf1bpp/mfbfont.c +hw/xfree86/xf1bpp/mfbgc.c +hw/xfree86/xf1bpp/mfbgetsp.c +hw/xfree86/xf1bpp/mfbigbblak.c +hw/xfree86/xf1bpp/mfbigbwht.c +hw/xfree86/xf1bpp/mfbhrzvert.c +hw/xfree86/xf1bpp/mfbimage.c +hw/xfree86/xf1bpp/mfbline.c +hw/xfree86/xf1bpp/mfbmisc.c +hw/xfree86/xf1bpp/mfbpablack.c +hw/xfree86/xf1bpp/mfbpainv.c +hw/xfree86/xf1bpp/mfbpawhite.c +hw/xfree86/xf1bpp/mfbpgbblak.c +hw/xfree86/xf1bpp/mfbpgbinv.c +hw/xfree86/xf1bpp/mfbpgbwht.c +hw/xfree86/xf1bpp/mfbpixmap.c +hw/xfree86/xf1bpp/mfbplyblack.c +hw/xfree86/xf1bpp/mfbplyinv.c +hw/xfree86/xf1bpp/mfbplywhite.c +hw/xfree86/xf1bpp/mfbpntwin.c +hw/xfree86/xf1bpp/mfbpolypnt.c +hw/xfree86/xf1bpp/mfbpushpxl.c +hw/xfree86/xf1bpp/mfbscrclse.c +hw/xfree86/xf1bpp/mfbscrinit.c +hw/xfree86/xf1bpp/mfbseg.c +hw/xfree86/xf1bpp/mfbsetsp.c +hw/xfree86/xf1bpp/mfbteblack.c +hw/xfree86/xf1bpp/mfbtewhite.c +hw/xfree86/xf1bpp/mfbtileC.c +hw/xfree86/xf1bpp/mfbtileG.c +hw/xfree86/xf1bpp/mfbwindow.c +hw/xfree86/xf1bpp/mfbzerarc.c +hw/xfree86/xf4bpp/mfbseg.c +hw/xfree86/xf8_32bpp/cfbgc32.c +hw/xfree86/xf8_32bpp/cfbgc8.c +hw/xfree86/xorg.c +hw/xfree86/xorg.conf.example +hw/xfree86/xorg.conf.example.pre +hw/xnest/Xnest +hw/xnest/Xnest.1x +hw/xnest/Xnest.man +hw/xprint/Xprt +hw/xprint/config/C/print/Xprinters.ghostscript +hw/xprint/doc/Xprt.1x +hw/xprint/doc/Xprt.man +hw/xprint/dpmsstubs-wrapper.c +hw/xprint/miinitext-wrapper.c +include/dix-config.h +include/kdrive-config.h +include/xgl-config.h +include/xkb-config.h +include/xorg-config.h +include/xorg-server.h +include/xwin-config.h +mfb/mfbbltC.c +mfb/mfbbltCI.c +mfb/mfbbltG.c +mfb/mfbbltO.c +mfb/mfbbltX.c +mfb/mfbigbblak.c +mfb/mfbigbwht.c +mfb/mfbpablack.c +mfb/mfbpainv.c +mfb/mfbpawhite.c +mfb/mfbpgbblak.c +mfb/mfbpgbinv.c +mfb/mfbpgbwht.c +mfb/mfbplyblack.c +mfb/mfbplyinv.c +mfb/mfbplywhite.c +mfb/mfbseg.c +mfb/mfbteblack.c +mfb/mfbtewhite.c +mfb/mfbtileC.c +mfb/mfbtileG.c diff --git a/import.log b/import.log new file mode 100644 index 0000000..1ad969a --- /dev/null +++ b/import.log @@ -0,0 +1 @@ +xorg-x11-server-1_5_0-1_fc10:HEAD:xorg-x11-server-1.5.0-1.fc10.src.rpm:1220485219 diff --git a/make-git-snapshot.sh b/make-git-snapshot.sh deleted file mode 100755 index f7e3bc9..0000000 --- a/make-git-snapshot.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -DIRNAME=xorg-server-$( date +%Y%m%d ) - -rm -rf $DIRNAME -git clone -n git://git.freedesktop.org/git/xorg/xserver $DIRNAME -cd $DIRNAME -if [ -z "$1" ]; then - git checkout --track -b server-1.5-branch origin/server-1.5-branch -else - git checkout $1 -fi -git log | head -1 | awk '{ print $2 }' > ../commitid -git repack -a -d -cd .. -tar jcf $DIRNAME.tar.bz2 $DIRNAME -rm -rf $DIRNAME diff --git a/sources b/sources index ffea069..901aa64 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -d225476fea6721d9f64c3268e47d6c51 xorg-server-1.4.99.906.tar.bz2 +9a817e5f7374d45b4dbe64b21bc0fb61 xorg-server-1.5.0.tar.bz2 diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 2919eb7..4b6acff 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -18,8 +18,8 @@ Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.4.99.906 -Release: 10%{?dist} +Version: 1.5.0 +Release: 1%{?dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -33,6 +33,7 @@ Source1: make-git-snapshot.sh Source2: commitid %else Source0: http://www.x.org/pub/individual/xserver/%{pkgname}-%{version}.tar.bz2 +Source1: gitignore %endif # keyboard enablement @@ -42,7 +43,8 @@ Source11: fedora-setup-keyboard # OpenGL compositing manager feature/optimization patches. Patch100: xorg-x11-server-1.1.0-no-move-damage.patch Patch101: xserver-1.4.99-dont-backfill-bg-none.patch -Patch102: xserver-1.4.99-exa-master-upgrade.patch +# XXX does this need rebasing still? +#Patch102: xserver-1.4.99-exa-master-upgrade.patch Patch103: xserver-1.5.0-bg-none-root.patch # Red Hat specific tweaking, not intended for upstream @@ -65,9 +67,9 @@ Patch5007: xserver-1.5.0-bad-fbdev-thats-mine.patch Patch5011: xserver-1.4.99-endian.patch # evdev keyboard map fix -Patch5013: xserver-1.5.0-xkb-fix-ProcXkbSetXYZ-to-work-on-all.patch +#Patch5013: xserver-1.5.0-xkb-fix-ProcXkbSetXYZ-to-work-on-all.patch Patch5014: xserver-1.5.0-force-SwitchCoreKeyboard-for-evdev.patch -Patch5015: xserver-1.5.0-enable-selinux.patch +# Patch5015: xserver-1.5.0-enable-selinux.patch Patch6000: xserver-1.5.0-hide-cursor.patch Patch6001: xserver-1.5.0-edid-backport.patch @@ -276,6 +278,7 @@ if [ -z "$GIT_COMMITTER_NAME" ]; then git-config user.email "x@fedoraproject.org" git-config user.name "Fedora X Ninjas" fi +cp %{SOURCE1} .gitignore git-add . git-commit -a -q -m "%{version} baseline." %endif @@ -495,6 +498,12 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Sep 03 2008 Adam Jackson 1.5.0-1 +- xserver 1.5.0 +- Revert to the EXA from 1.5.0, should be good enough one hopes. +- Add .gitignore from git, so working with the artificial git tree is less + flakey. + * Mon Aug 25 2008 Adam Jackson 1.4.99.906-10 - xserver-1.5.0-edid-backport.patch: Backport EDID updates from master. diff --git a/xserver-1.4.99-exa-master-upgrade.patch b/xserver-1.4.99-exa-master-upgrade.patch deleted file mode 100644 index 37b9443..0000000 --- a/xserver-1.4.99-exa-master-upgrade.patch +++ /dev/null @@ -1,1982 +0,0 @@ -From 82c5e0d932e4cd068396e793e71a3b405dff5c83 Mon Sep 17 00:00:00 2001 -From: Fedora X Ninjas -Date: Thu, 14 Aug 2008 19:05:38 +1000 -Subject: [PATCH] exa: update to latest EXA code from master - ---- - exa/Makefile.am | 1 + - exa/exa.c | 58 ++- - exa/exa_accel.c | 185 +++++++--- - exa/exa_glyphs.c | 897 ++++++++++++++++++++++++++++++++++++++++++++ - exa/exa_migration.c | 8 +- - exa/exa_priv.h | 67 +++- - exa/exa_render.c | 287 +++++++++++++-- - exa/exa_unaccel.c | 30 +- - hw/xfree86/exa/exa.man.pre | 6 - - hw/xfree86/exa/examodule.c | 9 +- - 10 files changed, 1406 insertions(+), 142 deletions(-) - create mode 100644 exa/exa_glyphs.c - -diff --git a/exa/Makefile.am b/exa/Makefile.am -index e2f7ed3..2b3f1e4 100644 ---- a/exa/Makefile.am -+++ b/exa/Makefile.am -@@ -18,6 +18,7 @@ libexa_la_SOURCES = \ - exa.c \ - exa.h \ - exa_accel.c \ -+ exa_glyphs.c \ - exa_migration.c \ - exa_offscreen.c \ - exa_render.c \ -diff --git a/exa/exa.c b/exa/exa.c -index 4bd3d81..c276d9a 100644 ---- a/exa/exa.c -+++ b/exa/exa.c -@@ -35,8 +35,6 @@ - #include - - #include "exa_priv.h" --#include --#include "dixfontstr.h" - #include "exa.h" - #include "cw.h" - -@@ -161,7 +159,7 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2) - RegionPtr pDamageReg; - RegionRec region; - -- if (!pExaPixmap) -+ if (!pExaPixmap || !pExaPixmap->pDamage) - return; - - box.x1 = max(x1, 0); -@@ -261,6 +259,21 @@ exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - pExaScr->info->pixmapPitchAlign); - } - -+ -+static void -+ExaDamageReport(DamagePtr pDamage, RegionPtr pReg, void *pClosure) -+{ -+ PixmapPtr pPixmap = pClosure; -+ ExaPixmapPriv(pPixmap); -+ RegionPtr pDamageReg = DamageRegion(pDamage); -+ -+ if (pExaPixmap->pendingDamage) { -+ REGION_UNION(pScreen, pDamageReg, pDamageReg, pReg); -+ pExaPixmap->pendingDamage = FALSE; -+ } -+} -+ -+ - /** - * exaCreatePixmap() creates a new pixmap. - * -@@ -321,6 +334,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - paddedWidth, NULL); - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - pExaPixmap->fb_ptr = NULL; -+ pExaPixmap->pDamage = NULL; - } else { - pExaPixmap->driverPriv = NULL; - /* Scratch pixmaps may have w/h equal to zero, and may not be -@@ -345,21 +359,22 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - fbDestroyPixmap(pPixmap); - return NULL; - } -- } -- -- pExaPixmap->area = NULL; - -- /* Set up damage tracking */ -- pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, -- pScreen, pPixmap); -+ /* Set up damage tracking */ -+ pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL, -+ DamageReportRawRegion, TRUE, -+ pScreen, pPixmap); - -- if (pExaPixmap->pDamage == NULL) { -- fbDestroyPixmap (pPixmap); -- return NULL; -- } -+ if (pExaPixmap->pDamage == NULL) { -+ fbDestroyPixmap (pPixmap); -+ return NULL; -+ } - -- DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); -- DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); -+ DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); -+ DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); -+ } -+ -+ pExaPixmap->area = NULL; - - /* None of the pixmap bits are valid initially */ - REGION_NULL(pScreen, &pExaPixmap->validSys); -@@ -737,6 +752,8 @@ exaCloseScreen(int i, ScreenPtr pScreen) - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - #endif - -+ exaGlyphsFini(pScreen); -+ - pScreen->CreateGC = pExaScr->SavedCreateGC; - pScreen->CloseScreen = pExaScr->SavedCloseScreen; - pScreen->GetImage = pExaScr->SavedGetImage; -@@ -750,8 +767,9 @@ exaCloseScreen(int i, ScreenPtr pScreen) - #ifdef RENDER - if (ps) { - ps->Composite = pExaScr->SavedComposite; -+ ps->Glyphs = pExaScr->SavedGlyphs; - ps->Trapezoids = pExaScr->SavedTrapezoids; -- ps->AddTraps = pExaScr->SavedAddTraps; -+ ps->Triangles = pExaScr->SavedTriangles; - } - #endif - -@@ -913,14 +931,14 @@ exaDriverInit (ScreenPtr pScreen, - pExaScr->SavedComposite = ps->Composite; - ps->Composite = exaComposite; - -+ pExaScr->SavedGlyphs = ps->Glyphs; -+ ps->Glyphs = exaGlyphs; -+ - pExaScr->SavedTriangles = ps->Triangles; - ps->Triangles = exaTriangles; - - pExaScr->SavedTrapezoids = ps->Trapezoids; - ps->Trapezoids = exaTrapezoids; -- -- pExaScr->SavedAddTraps = ps->AddTraps; -- ps->AddTraps = ExaCheckAddTraps; - } - #endif - -@@ -975,6 +993,8 @@ exaDriverInit (ScreenPtr pScreen, - } - } - -+ exaGlyphsInit(pScreen); -+ - LogMessage(X_INFO, "EXA(%d): Driver registered support for the following" - " operations:\n", pScreen->myNum); - assert(pScreenInfo->PrepareSolid != NULL); -diff --git a/exa/exa_accel.c b/exa/exa_accel.c -index d66dd47..8ac21b8 100644 ---- a/exa/exa_accel.c -+++ b/exa/exa_accel.c -@@ -144,7 +144,6 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - ExaScreenPriv (pDrawable->pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv(pPix); -- ExaMigrationRec pixmaps[1]; - RegionPtr pClip; - BoxPtr pbox; - int nbox; -@@ -166,11 +165,16 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - if (pExaScr->swappedOut) - return FALSE; - -- pixmaps[0].as_dst = TRUE; -- pixmaps[0].as_src = FALSE; -- pixmaps[0].pPix = pPix; -- pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); -- exaDoMigration (pixmaps, 1, TRUE); -+ if (pExaPixmap->pDamage) { -+ ExaMigrationRec pixmaps[1]; -+ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = FALSE; -+ pixmaps[0].pPix = pPix; -+ pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); -+ -+ exaDoMigration (pixmaps, 1, TRUE); -+ } - - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - -@@ -261,20 +265,16 @@ exaDoShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, - - if (format == ZPixmap) - { -- PixmapPtr pPixmap; -+ PixmapPtr pPixmap = -+ GetScratchPixmapHeader(pDrawable->pScreen, w, h, depth, -+ BitsPerPixel(depth), PixmapBytePad(w, depth), -+ (pointer)data); - -- pPixmap = GetScratchPixmapHeader(pDrawable->pScreen, w, h, depth, -- BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data); - if (!pPixmap) - return FALSE; - -- if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, -- pGC->alu)) -- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); -- else -- ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST); -- fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy); -- exaFinishAccess(pDrawable, EXA_PREPARE_DEST); -+ pGC->ops->CopyArea(&pPixmap->drawable, pDrawable, pGC, sx, sy, sw, sh, -+ dx, dy); - - FreeScratchPixmapHeader(pPixmap); - -@@ -301,14 +301,19 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format, - .x2 = pDrawable->x + dx + sw, .y2 = pDrawable->y + dy + sh }; - RegionRec region; - int xoff, yoff; -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ RegionPtr pending_damage = NULL; - -- REGION_INIT(pScreen, ®ion, &box, 1); -+ if (pExaPixmap->pDamage) -+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - -- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); -+ if (pending_damage) { -+ REGION_INIT(pScreen, ®ion, &box, 1); - -- REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); -- REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); -+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); -+ -+ REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); -+ REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); -+ } - - if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, - dx, dy, data)) { -@@ -316,16 +321,18 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format, - pGC->alu)) - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - else -- ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST); -+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, ®ion); - fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, - data); - exaFinishAccess(pDrawable, EXA_PREPARE_DEST); - } - -- REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff); -- DamageDamageRegion(pDrawable, ®ion); -+ if (pending_damage) { -+ REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff); -+ DamageDamageRegion(pDrawable, ®ion); - -- REGION_UNINIT(pScreen, ®ion); -+ REGION_UNINIT(pScreen, ®ion); -+ } - } - - ShmFuncs exaShmFuncs = { NULL, exaShmPutImage }; -@@ -533,16 +540,36 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, - pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); - - /* Check whether the accelerator can use this pixmap. -- * FIXME: If it cannot, use temporary pixmaps so that the drawing -- * happens within limits. -+ * If the pitch of the pixmaps is out of range, there's nothing -+ * we can do but fall back to software rendering. - */ -- if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) -- { -+ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || -+ pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) - goto fallback; -- } else { -- exaDoMigration (pixmaps, 2, TRUE); -+ -+ /* If the width or the height of either of the pixmaps -+ * is out of range, check whether the boxes are actually out of the -+ * addressable range as well. If they aren't, we can still do -+ * the copying in hardware. -+ */ -+ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { -+ int i; -+ -+ for (i = 0; i < nbox; i++) { -+ /* src */ -+ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || -+ (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) -+ goto fallback; -+ -+ /* dst */ -+ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || -+ (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) -+ goto fallback; -+ } - } - -+ exaDoMigration (pixmaps, 2, TRUE); -+ - /* Mixed directions must be handled specially if the card is lame */ - if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && - reverse != upsidedown) { -@@ -952,16 +979,23 @@ exaImageGlyphBlt (DrawablePtr pDrawable, - FbBits depthMask; - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - ExaPixmapPriv(pPixmap); -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- BoxRec extents = *REGION_EXTENTS(pScreen, pending_damage); -+ RegionPtr pending_damage = NULL; -+ BoxRec extents; - int xoff, yoff; - -- if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2) -- return; -+ if (pExaPixmap->pDamage) -+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - -- depthMask = FbFullMask(pDrawable->depth); -+ if (pending_damage) { -+ extents = *REGION_EXTENTS(pScreen, pending_damage); -+ -+ if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2) -+ return; - -- if ((pGC->planemask & depthMask) != depthMask) -+ depthMask = FbFullMask(pDrawable->depth); -+ } -+ -+ if (!pending_damage || (pGC->planemask & depthMask) != depthMask) - { - ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); - return; -@@ -1195,6 +1229,7 @@ exaFillRegionTiled (DrawablePtr pDrawable, - int nbox = REGION_NUM_RECTS (pRegion); - BoxPtr pBox = REGION_RECTS (pRegion); - Bool ret = FALSE; -+ int i; - - tileWidth = pTile->drawable.width; - tileHeight = pTile->drawable.height; -@@ -1217,14 +1252,11 @@ exaFillRegionTiled (DrawablePtr pDrawable, - pixmaps[1].pPix = pTile; - pixmaps[1].pReg = NULL; - -- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); -- REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); -- - pExaPixmap = ExaGetPixmapPriv (pPixmap); - - if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) - { -- goto out; -+ return FALSE; - } else { - exaDoMigration (pixmaps, 2, TRUE); - } -@@ -1232,24 +1264,33 @@ exaFillRegionTiled (DrawablePtr pDrawable, - pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - - if (!pPixmap || !exaPixmapIsOffscreen(pTile)) -- goto out; -+ return FALSE; - - if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) - { -- while (nbox--) -+ if (xoff || yoff) -+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); -+ -+ for (i = 0; i < nbox; i++) - { -- int height = pBox->y2 - pBox->y1; -- int dstY = pBox->y1; -+ int height = pBox[i].y2 - pBox[i].y1; -+ int dstY = pBox[i].y1; - int tileY; - -+ if (alu == GXcopy) -+ height = min(height, tileHeight); -+ - modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); - - while (height > 0) { -- int width = pBox->x2 - pBox->x1; -- int dstX = pBox->x1; -+ int width = pBox[i].x2 - pBox[i].x1; -+ int dstX = pBox[i].x1; - int tileX; - int h = tileHeight - tileY; - -+ if (alu == GXcopy) -+ width = min(width, tileWidth); -+ - if (h > height) - h = height; - height -= h; -@@ -1271,17 +1312,57 @@ exaFillRegionTiled (DrawablePtr pDrawable, - dstY += h; - tileY = 0; - } -- pBox++; - } - (*pExaScr->info->DoneCopy) (pPixmap); -+ -+ /* With GXcopy, we only need to do the basic algorithm up to the tile -+ * size; then, we can just keep doubling the destination in each -+ * direction until it fills the box. This way, the number of copy -+ * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where -+ * rx/ry is the ratio between box and tile width/height. This can make -+ * a big difference if each driver copy incurs a significant constant -+ * overhead. -+ */ -+ if (alu != GXcopy) -+ ret = TRUE; -+ else if ((*pExaScr->info->PrepareCopy) (pPixmap, pPixmap, 1, 1, alu, -+ planemask)) { -+ for (i = 0; i < nbox; i++) -+ { -+ int dstX = pBox[i].x1 + tileWidth; -+ int dstY = pBox[i].y1 + tileHeight; -+ int width = min(pBox[i].x2 - dstX, tileWidth); -+ int height = min(pBox[i].y2 - pBox[i].y1, tileHeight); -+ -+ while (dstX < pBox[i].x2) { -+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, -+ dstX, pBox[i].y1, width, height); -+ dstX += width; -+ width = min(pBox[i].x2 - dstX, width * 2); -+ } -+ -+ width = pBox[i].x2 - pBox[i].x1; -+ height = min(pBox[i].y2 - dstY, tileHeight); -+ -+ while (dstY < pBox[i].y2) { -+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, -+ pBox[i].x1, dstY, width, height); -+ dstY += height; -+ height = min(pBox[i].y2 - dstY, height * 2); -+ } -+ } -+ -+ (*pExaScr->info->DoneCopy) (pPixmap); -+ -+ ret = TRUE; -+ } -+ - exaMarkSync(pDrawable->pScreen); - -- ret = TRUE; -+ if (xoff || yoff) -+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); - } - --out: -- REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); -- - return ret; - } - -diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c -new file mode 100644 -index 0000000..ff665d5 ---- /dev/null -+++ b/exa/exa_glyphs.c -@@ -0,0 +1,897 @@ -+/* -+ * Copyright © 2008 Red Hat, Inc. -+ * Partly based on code 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 Red Hat not be used in advertising or -+ * publicity pertaining to distribution of the software without specific, -+ * written prior permission. Red Hat makes no representations about the -+ * suitability of this software for any purpose. It is provided "as is" -+ * without express or implied warranty. -+ * -+ * Red Hat DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL Red Hat -+ * 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. -+ * -+ * 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: Owen Taylor -+ * Based on code by: Keith Packard -+ */ -+ -+#ifdef HAVE_DIX_CONFIG_H -+#include -+#endif -+ -+#include -+ -+#include "exa_priv.h" -+ -+#include "mipict.h" -+ -+#if DEBUG_GLYPH_CACHE -+#define DBG_GLYPH_CACHE(a) ErrorF a -+#else -+#define DBG_GLYPH_CACHE(a) -+#endif -+ -+/* Width of the pixmaps we use for the caches; this should be less than -+ * max texture size of the driver; this may need to actually come from -+ * the driver. -+ */ -+#define CACHE_PICTURE_WIDTH 1024 -+ -+/* Maximum number of glyphs we buffer on the stack before flushing -+ * rendering to the mask or destination surface. -+ */ -+#define GLYPH_BUFFER_SIZE 256 -+ -+typedef struct { -+ PicturePtr source; -+ ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE]; -+ int count; -+} ExaGlyphBuffer, *ExaGlyphBufferPtr; -+ -+typedef enum { -+ ExaGlyphSuccess, /* Glyph added to render buffer */ -+ ExaGlyphFail, /* out of memory, etc */ -+ ExaGlyphNeedFlush, /* would evict a glyph already in the buffer */ -+} ExaGlyphCacheResult; -+ -+void -+exaGlyphsInit(ScreenPtr pScreen) -+{ -+ ExaScreenPriv(pScreen); -+ int i = 0; -+ -+ memset(pExaScr->glyphCaches, 0, sizeof(pExaScr->glyphCaches)); -+ -+ pExaScr->glyphCaches[i].format = PICT_a8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 16; -+ i++; -+ pExaScr->glyphCaches[i].format = PICT_a8r8g8b8; -+ pExaScr->glyphCaches[i].glyphWidth = pExaScr->glyphCaches[i].glyphHeight = 32; -+ i++; -+ -+ assert(i == EXA_NUM_GLYPH_CACHES); -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ pExaScr->glyphCaches[i].columns = CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth; -+ pExaScr->glyphCaches[i].size = 256; -+ pExaScr->glyphCaches[i].hashSize = 557; -+ } -+} -+ -+static void -+exaUnrealizeGlyphCaches(ScreenPtr pScreen, -+ unsigned int format) -+{ -+ ExaScreenPriv(pScreen); -+ int i; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (cache->format != format) -+ continue; -+ -+ if (cache->picture) { -+ FreePicture ((pointer) cache->picture, (XID) 0); -+ cache->picture = NULL; -+ } -+ -+ if (cache->hashEntries) { -+ xfree(cache->hashEntries); -+ cache->hashEntries = NULL; -+ } -+ -+ if (cache->glyphs) { -+ xfree(cache->glyphs); -+ cache->glyphs = NULL; -+ } -+ cache->glyphCount = 0; -+ } -+} -+ -+/* All caches for a single format share a single pixmap for glyph storage, -+ * allowing mixing glyphs of different sizes without paying a penalty -+ * for switching between source pixmaps. (Note that for a size of font -+ * right at the border between two sizes, we might be switching for almost -+ * every glyph.) -+ * -+ * This function allocates the storage pixmap, and then fills in the -+ * rest of the allocated structures for all caches with the given format. -+ */ -+static Bool -+exaRealizeGlyphCaches(ScreenPtr pScreen, -+ unsigned int format) -+{ -+ ExaScreenPriv(pScreen); -+ -+ int depth = PIXMAN_FORMAT_DEPTH(format); -+ PictFormatPtr pPictFormat; -+ PixmapPtr pPixmap; -+ PicturePtr pPicture; -+ int height; -+ int i; -+ int error; -+ -+ pPictFormat = PictureMatchFormat(pScreen, depth, format); -+ if (!pPictFormat) -+ return FALSE; -+ -+ /* Compute the total vertical size needed for the format */ -+ -+ height = 0; -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ int rows; -+ -+ if (cache->format != format) -+ continue; -+ -+ cache->yOffset = height; -+ -+ rows = (cache->size + cache->columns - 1) / cache->columns; -+ height += rows * cache->glyphHeight; -+ } -+ -+ /* Now allocate the pixmap and picture */ -+ -+ pPixmap = (*pScreen->CreatePixmap) (pScreen, -+ CACHE_PICTURE_WIDTH, -+ height, depth, 0); -+ if (!pPixmap) -+ return FALSE; -+ -+ pPicture = CreatePicture(0, &pPixmap->drawable, pPictFormat, -+ 0, 0, serverClient, &error); -+ -+ (*pScreen->DestroyPixmap) (pPixmap); /* picture holds a refcount */ -+ -+ if (!pPicture) -+ return FALSE; -+ -+ /* And store the picture in all the caches for the format */ -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ int j; -+ -+ if (cache->format != format) -+ continue; -+ -+ cache->picture = pPicture; -+ cache->picture->refcnt++; -+ cache->hashEntries = xalloc(sizeof(int) * cache->hashSize); -+ cache->glyphs = xalloc(sizeof(ExaCachedGlyphRec) * cache->size); -+ cache->glyphCount = 0; -+ -+ if (!cache->hashEntries || !cache->glyphs) -+ goto bail; -+ -+ for (j = 0; j < cache->hashSize; j++) -+ cache->hashEntries[j] = -1; -+ -+ cache->evictionPosition = rand() % cache->size; -+ } -+ -+ /* Each cache references the picture individually */ -+ FreePicture ((pointer) pPicture, (XID) 0); -+ return TRUE; -+ -+bail: -+ exaUnrealizeGlyphCaches(pScreen, format); -+ return FALSE; -+} -+ -+void -+exaGlyphsFini (ScreenPtr pScreen) -+{ -+ ExaScreenPriv(pScreen); -+ int i; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (cache->picture) -+ exaUnrealizeGlyphCaches(pScreen, cache->format); -+ } -+} -+ -+static int -+exaGlyphCacheHashLookup(ExaGlyphCachePtr cache, -+ GlyphPtr pGlyph) -+{ -+ int slot; -+ -+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ int entryPos = cache->hashEntries[slot]; -+ if (entryPos == -1) -+ return -1; -+ -+ if (memcmp(pGlyph->sha1, cache->glyphs[entryPos].sha1, sizeof(pGlyph->sha1)) == 0){ -+ return entryPos; -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+static void -+exaGlyphCacheHashInsert(ExaGlyphCachePtr cache, -+ GlyphPtr pGlyph, -+ int pos) -+{ -+ int slot; -+ -+ memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1)); -+ -+ slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ if (cache->hashEntries[slot] == -1) { -+ cache->hashEntries[slot] = pos; -+ return; -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+static void -+exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, -+ int pos) -+{ -+ int slot; -+ int emptiedSlot = -1; -+ -+ slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize; -+ -+ while (TRUE) { /* hash table can never be full */ -+ int entryPos = cache->hashEntries[slot]; -+ -+ if (entryPos == -1) -+ return; -+ -+ if (entryPos == pos) { -+ cache->hashEntries[slot] = -1; -+ emptiedSlot = slot; -+ } else if (emptiedSlot != -1) { -+ /* See if we can move this entry into the emptied slot, we can't -+ * do that if if entry would have hashed between the current position -+ * and the emptied slot. (taking wrapping into account). Bad positions -+ * are: -+ * -+ * | XXXXXXXXXX | -+ * i j -+ * -+ * |XXX XXXX| -+ * j i -+ * -+ * i - slot, j - emptiedSlot -+ * -+ * (Knuth 6.4R) -+ */ -+ -+ int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize; -+ -+ if (!((entrySlot >= slot && entrySlot < emptiedSlot) || -+ (emptiedSlot < slot && (entrySlot < emptiedSlot || entrySlot >= slot)))) -+ { -+ cache->hashEntries[emptiedSlot] = entryPos; -+ cache->hashEntries[slot] = -1; -+ emptiedSlot = slot; -+ } -+ } -+ -+ slot--; -+ if (slot < 0) -+ slot = cache->hashSize - 1; -+ } -+} -+ -+#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth) -+#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight) -+ -+/* The most efficient thing to way to upload the glyph to the screen -+ * is to use the UploadToScreen() driver hook; this allows us to -+ * pipeline glyph uploads and to avoid creating offscreen pixmaps for -+ * glyphs that we'll never use again. -+ */ -+static Bool -+exaGlyphCacheUploadGlyph(ScreenPtr pScreen, -+ ExaGlyphCachePtr cache, -+ int pos, -+ GlyphPtr pGlyph) -+{ -+ ExaScreenPriv(pScreen); -+ PicturePtr pGlyphPicture = GlyphPicture(pGlyph)[pScreen->myNum]; -+ PixmapPtr pGlyphPixmap = (PixmapPtr)pGlyphPicture->pDrawable; -+ ExaPixmapPriv(pGlyphPixmap); -+ PixmapPtr pCachePixmap = (PixmapPtr)cache->picture->pDrawable; -+ ExaMigrationRec pixmaps[1]; -+ int cacheXoff, cacheYoff; -+ -+ if (!pExaScr->info->UploadToScreen || pExaScr->swappedOut || pExaPixmap->accel_blocked) -+ return FALSE; -+ -+ /* If the glyph pixmap is already uploaded, no point in doing -+ * things this way */ -+ if (exaPixmapIsOffscreen(pGlyphPixmap)) -+ return FALSE; -+ -+ /* UploadToScreen only works if bpp match */ -+ if (pGlyphPixmap->drawable.bitsPerPixel != pCachePixmap->drawable.bitsPerPixel) -+ return FALSE; -+ -+ /* cache pixmap must be offscreen. */ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = FALSE; -+ pixmaps[0].pPix = pCachePixmap; -+ pixmaps[0].pReg = NULL; -+ exaDoMigration (pixmaps, 1, TRUE); -+ -+ pCachePixmap = exaGetOffscreenPixmap ((DrawablePtr)pCachePixmap, &cacheXoff, &cacheYoff); -+ if (!pCachePixmap) -+ return FALSE; -+ -+ if (!pExaScr->info->UploadToScreen(pCachePixmap, -+ CACHE_X(pos) + cacheXoff, -+ CACHE_Y(pos) + cacheYoff, -+ pGlyph->info.width, -+ pGlyph->info.height, -+ (char *)pExaPixmap->sys_ptr, -+ pExaPixmap->sys_pitch)) -+ return FALSE; -+ -+ exaPixmapDirty (pCachePixmap, -+ CACHE_X(pos) + cacheXoff, -+ CACHE_Y(pos) + cacheYoff, -+ CACHE_X(pos) + cacheXoff + pGlyph->info.width, -+ CACHE_Y(pos) + cacheYoff + pGlyph->info.height); -+ -+ return TRUE; -+} -+ -+static ExaGlyphCacheResult -+exaGlyphCacheBufferGlyph(ScreenPtr pScreen, -+ ExaGlyphCachePtr cache, -+ ExaGlyphBufferPtr buffer, -+ GlyphPtr pGlyph, -+ int xGlyph, -+ int yGlyph) -+{ -+ ExaCompositeRectPtr rect; -+ int pos; -+ -+ if (buffer->source && buffer->source != cache->picture) -+ return ExaGlyphNeedFlush; -+ -+ if (!cache->picture) { -+ if (!exaRealizeGlyphCaches(pScreen, cache->format)) -+ return ExaGlyphFail; -+ } -+ -+ DBG_GLYPH_CACHE(("(%d,%d,%s): buffering glyph %lx\n", -+ cache->glyphWidth, cache->glyphHeight, cache->format == PICT_a8 ? "A" : "ARGB", -+ (long)*(CARD32 *) pGlyph->sha1)); -+ -+ pos = exaGlyphCacheHashLookup(cache, pGlyph); -+ if (pos != -1) { -+ DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); -+ } else { -+ if (cache->glyphCount < cache->size) { -+ /* Space remaining; we fill from the start */ -+ pos = cache->glyphCount; -+ cache->glyphCount++; -+ DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); -+ -+ exaGlyphCacheHashInsert(cache, pGlyph, pos); -+ -+ } else { -+ /* Need to evict an entry. We have to see if any glyphs -+ * already in the output buffer were at this position in -+ * the cache -+ */ -+ -+ pos = cache->evictionPosition; -+ DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); -+ if (buffer->count) { -+ int x, y; -+ int i; -+ -+ x = CACHE_X(pos); -+ y = CACHE_Y(pos); -+ -+ for (i = 0; i < buffer->count; i++) { -+ if (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y) { -+ DBG_GLYPH_CACHE((" must flush buffer\n")); -+ return ExaGlyphNeedFlush; -+ } -+ } -+ } -+ -+ /* OK, we're all set, swap in the new glyph */ -+ exaGlyphCacheHashRemove(cache, pos); -+ exaGlyphCacheHashInsert(cache, pGlyph, pos); -+ -+ /* And pick a new eviction position */ -+ cache->evictionPosition = rand() % cache->size; -+ } -+ -+ /* Now actually upload the glyph into the cache picture; if -+ * we can't do it with UploadToScreen (because the glyph is -+ * offscreen, etc), we fall back to CompositePicture. -+ */ -+ if (!exaGlyphCacheUploadGlyph(pScreen, cache, pos, pGlyph)) { -+ CompositePicture (PictOpSrc, -+ GlyphPicture(pGlyph)[pScreen->myNum], -+ None, -+ cache->picture, -+ 0, 0, -+ 0, 0, -+ CACHE_X(pos), -+ CACHE_Y(pos), -+ pGlyph->info.width, -+ pGlyph->info.height); -+ } -+ -+ } -+ -+ -+ buffer->source = cache->picture; -+ -+ rect = &buffer->rects[buffer->count]; -+ rect->xSrc = CACHE_X(pos); -+ rect->ySrc = CACHE_Y(pos); -+ rect->xDst = xGlyph - pGlyph->info.x; -+ rect->yDst = yGlyph - pGlyph->info.y; -+ rect->width = pGlyph->info.width; -+ rect->height = pGlyph->info.height; -+ -+ buffer->count++; -+ -+ return ExaGlyphSuccess; -+} -+ -+#undef CACHE_X -+#undef CACHE_Y -+ -+static ExaGlyphCacheResult -+exaBufferGlyph(ScreenPtr pScreen, -+ ExaGlyphBufferPtr buffer, -+ GlyphPtr pGlyph, -+ int xGlyph, -+ int yGlyph) -+{ -+ ExaScreenPriv(pScreen); -+ unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format; -+ int width = pGlyph->info.width; -+ int height = pGlyph->info.height; -+ ExaCompositeRectPtr rect; -+ PicturePtr source; -+ int i; -+ -+ if (buffer->count == GLYPH_BUFFER_SIZE) -+ return ExaGlyphNeedFlush; -+ -+ if (PICT_FORMAT_BPP(format) == 1) -+ format = PICT_a8; -+ -+ for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) { -+ ExaGlyphCachePtr cache = &pExaScr->glyphCaches[i]; -+ -+ if (format == cache->format && -+ width <= cache->glyphWidth && -+ height <= cache->glyphHeight) { -+ ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr->glyphCaches[i], -+ buffer, -+ pGlyph, xGlyph, yGlyph); -+ switch (result) { -+ case ExaGlyphFail: -+ break; -+ case ExaGlyphSuccess: -+ case ExaGlyphNeedFlush: -+ return result; -+ } -+ } -+ } -+ -+ /* Couldn't find the glyph in the cache, use the glyph picture directly */ -+ -+ source = GlyphPicture(pGlyph)[pScreen->myNum]; -+ if (buffer->source && buffer->source != source) -+ return ExaGlyphNeedFlush; -+ -+ buffer->source = source; -+ -+ rect = &buffer->rects[buffer->count]; -+ rect->xSrc = 0; -+ rect->ySrc = 0; -+ rect->xDst = xGlyph - pGlyph->info.x; -+ rect->yDst = yGlyph - pGlyph->info.y; -+ rect->width = pGlyph->info.width; -+ rect->height = pGlyph->info.height; -+ -+ buffer->count++; -+ -+ return ExaGlyphSuccess; -+} -+ -+static void -+exaGlyphsToMask(PicturePtr pMask, -+ ExaGlyphBufferPtr buffer) -+{ -+ exaCompositeRects(PictOpAdd, buffer->source, pMask, -+ buffer->count, buffer->rects); -+ -+ buffer->count = 0; -+ buffer->source = NULL; -+} -+ -+static void -+exaGlyphsToDst(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ ExaGlyphBufferPtr buffer, -+ INT16 xSrc, -+ INT16 ySrc, -+ INT16 xDst, -+ INT16 yDst) -+{ -+ int i; -+ -+ for (i = 0; i < buffer->count; i++) { -+ ExaCompositeRectPtr rect = &buffer->rects[i]; -+ -+ CompositePicture (op, -+ pSrc, -+ buffer->source, -+ pDst, -+ xSrc + rect->xDst - xDst, -+ ySrc + rect->yDst - yDst, -+ rect->xSrc, -+ rect->ySrc, -+ rect->xDst, -+ rect->yDst, -+ rect->width, -+ rect->height); -+ } -+ -+ buffer->count = 0; -+ buffer->source = NULL; -+} -+ -+/* Cut and paste from render/glyph.c - probably should export it instead */ -+static void -+GlyphExtents (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; -+ } -+ } -+} -+ -+/** -+ * Returns TRUE if the glyphs in the lists intersect. Only checks based on -+ * bounding box, which appears to be good enough to catch most cases at least. -+ */ -+static Bool -+exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs) -+{ -+ int x1, x2, y1, y2; -+ int n; -+ GlyphPtr glyph; -+ int x, y; -+ BoxRec extents; -+ Bool first = TRUE; -+ -+ x = 0; -+ y = 0; -+ while (nlist--) { -+ x += list->xOff; -+ y += list->yOff; -+ n = list->len; -+ list++; -+ while (n--) { -+ glyph = *glyphs++; -+ -+ if (glyph->info.width == 0 || glyph->info.height == 0) { -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ continue; -+ } -+ -+ 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 (first) { -+ extents.x1 = x1; -+ extents.y1 = y1; -+ extents.x2 = x2; -+ extents.y2 = y2; -+ first = FALSE; -+ } else { -+ if (x1 < extents.x2 && x2 > extents.x1 && -+ y1 < extents.y2 && y2 > extents.y1) -+ { -+ return TRUE; -+ } -+ -+ 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; -+ } -+ } -+ -+ return FALSE; -+} -+ -+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) -+ -+void -+exaGlyphs (CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ PictFormatPtr maskFormat, -+ INT16 xSrc, -+ INT16 ySrc, -+ int nlist, -+ GlyphListPtr list, -+ GlyphPtr *glyphs) -+{ -+ 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 = {0, 0, 0, 0}; -+ CARD32 component_alpha; -+ ExaGlyphBuffer buffer; -+ -+ /* If we don't have a mask format but all the glyphs have the same format -+ * and don't intersect, use the glyph format as mask format for the full -+ * benefits of the glyph cache. -+ */ -+ if (!maskFormat) { -+ Bool sameFormat = TRUE; -+ int i; -+ -+ maskFormat = list[0].format; -+ -+ for (i = 0; i < nlist; i++) { -+ if (maskFormat->format != list[i].format->format) { -+ sameFormat = FALSE; -+ break; -+ } -+ } -+ -+ if (!sameFormat || (maskFormat->depth != 1 && -+ exaGlyphsIntersect(nlist, list, glyphs))) { -+ maskFormat = NULL; -+ } -+ } -+ -+ if (maskFormat) -+ { -+ GCPtr pGC; -+ xRectangle rect; -+ -+ GlyphExtents (nlist, list, glyphs, &extents); -+ -+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) -+ return; -+ width = extents.x2 - extents.x1; -+ height = extents.y2 - extents.y1; -+ -+ if (maskFormat->depth == 1) { -+ PictFormatPtr a8Format = PictureMatchFormat (pScreen, 8, PICT_a8); -+ -+ if (a8Format) -+ maskFormat = a8Format; -+ } -+ -+ pMaskPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, -+ maskFormat->depth, -+ CREATE_PIXMAP_USAGE_SCRATCH); -+ 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; -+ } -+ buffer.count = 0; -+ buffer.source = NULL; -+ while (nlist--) -+ { -+ x += list->xOff; -+ y += list->yOff; -+ n = list->len; -+ while (n--) -+ { -+ glyph = *glyphs++; -+ pPicture = GlyphPicture (glyph)[pScreen->myNum]; -+ -+ if (glyph->info.width > 0 && glyph->info.height > 0 && -+ exaBufferGlyph(pScreen, &buffer, glyph, x, y) == ExaGlyphNeedFlush) -+ { -+ if (maskFormat) -+ exaGlyphsToMask(pMask, &buffer); -+ else -+ exaGlyphsToDst(op, pSrc, pDst, &buffer, -+ xSrc, ySrc, xDst, yDst); -+ -+ exaBufferGlyph(pScreen, &buffer, glyph, x, y); -+ } -+ -+ x += glyph->info.xOff; -+ y += glyph->info.yOff; -+ } -+ list++; -+ } -+ -+ if (maskFormat) -+ exaGlyphsToMask(pMask, &buffer); -+ else -+ exaGlyphsToDst(op, pSrc, pDst, &buffer, -+ xSrc, ySrc, xDst, yDst); -+ -+ 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/exa/exa_migration.c b/exa/exa_migration.c -index 5f22474..25ea73d 100644 ---- a/exa/exa_migration.c -+++ b/exa/exa_migration.c -@@ -33,8 +33,6 @@ - #include - - #include "exa_priv.h" --#include --#include "dixfontstr.h" - #include "exa.h" - #include "cw.h" - -@@ -301,6 +299,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) - ExaScreenPriv (pScreen); - ExaPixmapPriv (pPixmap); - -+ if (migrate->as_dst) -+ pExaPixmap->pendingDamage = TRUE; -+ - /* If we're VT-switched away, no touching card memory allowed. */ - if (pExaScr->swappedOut) - return; -@@ -369,6 +370,9 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate) - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - -+ if (migrate->as_dst) -+ pExaPixmap->pendingDamage = TRUE; -+ - if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap)) - return; - -diff --git a/exa/exa_priv.h b/exa/exa_priv.h -index 21e6f0b..9ec2a56 100644 ---- a/exa/exa_priv.h -+++ b/exa/exa_priv.h -@@ -61,6 +61,7 @@ - #define DEBUG_MIGRATE 0 - #define DEBUG_PIXMAP 0 - #define DEBUG_OFFSCREEN 0 -+#define DEBUG_GLYPH_CACHE 0 - - #if DEBUG_TRACE_FALL - #define EXA_FALLBACK(x) \ -@@ -95,6 +96,38 @@ enum ExaMigrationHeuristic { - ExaMigrationSmart - }; - -+typedef struct { -+ unsigned char sha1[20]; -+} ExaCachedGlyphRec, *ExaCachedGlyphPtr; -+ -+typedef struct { -+ /* The identity of the cache, statically configured at initialization */ -+ unsigned int format; -+ int glyphWidth; -+ int glyphHeight; -+ -+ int size; /* Size of cache; eventually this should be dynamically determined */ -+ -+ /* Hash table mapping from glyph sha1 to position in the glyph; we use -+ * open addressing with a hash table size determined based on size and large -+ * enough so that we always have a good amount of free space, so we can -+ * use linear probing. (Linear probing is preferrable to double hashing -+ * here because it allows us to easily remove entries.) -+ */ -+ int *hashEntries; -+ int hashSize; -+ -+ ExaCachedGlyphPtr glyphs; -+ int glyphCount; /* Current number of glyphs */ -+ -+ PicturePtr picture; /* Where the glyphs of the cache are stored */ -+ int yOffset; /* y location within the picture where the cache starts */ -+ int columns; /* Number of columns the glyphs are layed out in */ -+ int evictionPosition; /* Next random position to evict a glyph */ -+} ExaGlyphCacheRec, *ExaGlyphCachePtr; -+ -+#define EXA_NUM_GLYPH_CACHES 4 -+ - typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); - typedef struct { - ExaDriverPtr info; -@@ -114,7 +147,6 @@ typedef struct { - TrianglesProcPtr SavedTriangles; - GlyphsProcPtr SavedGlyphs; - TrapezoidsProcPtr SavedTrapezoids; -- AddTrapsProcPtr SavedAddTraps; - #endif - - Bool swappedOut; -@@ -123,6 +155,8 @@ typedef struct { - unsigned disableFbCount; - Bool optimize_migration; - unsigned offScreenCounter; -+ -+ ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; - } ExaScreenPrivRec, *ExaScreenPrivPtr; - - /* -@@ -192,6 +226,7 @@ typedef struct { - * location. - */ - DamagePtr pDamage; -+ Bool pendingDamage; - /** - * The valid regions mark the valid bits (at least, as they're derived from - * damage, which may be overreported) of a pixmap's system and FB copies. -@@ -210,6 +245,15 @@ typedef struct _ExaMigrationRec { - RegionPtr pReg; - } ExaMigrationRec, *ExaMigrationPtr; - -+typedef struct { -+ INT16 xSrc; -+ INT16 ySrc; -+ INT16 xDst; -+ INT16 yDst; -+ INT16 width; -+ INT16 height; -+} ExaCompositeRectRec, *ExaCompositeRectPtr; -+ - /** - * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place - * to set EXA options or hook in screen functions to handle using EXA as the AA. -@@ -294,13 +338,6 @@ ExaCheckGetSpans (DrawablePtr pDrawable, - int nspans, - char *pdstStart); - --void --ExaCheckAddTraps (PicturePtr pPicture, -- INT16 x_off, -- INT16 y_off, -- int ntrap, -- xTrap *traps); -- - /* exa_accel.c */ - - static _X_INLINE Bool -@@ -431,6 +468,13 @@ exaComposite(CARD8 op, - CARD16 height); - - void -+exaCompositeRects(CARD8 op, -+ PicturePtr Src, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects); -+ -+void - exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntrap, xTrapezoid *traps); -@@ -440,6 +484,13 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntri, xTriangle *tris); - -+/* exa_glyph.c */ -+void -+exaGlyphsInit(ScreenPtr pScreen); -+ -+void -+exaGlyphsFini (ScreenPtr pScreen); -+ - void - exaGlyphs (CARD8 op, - PicturePtr pSrc, -diff --git a/exa/exa_render.c b/exa/exa_render.c -index 1d7b897..7042285 100644 ---- a/exa/exa_render.c -+++ b/exa/exa_render.c -@@ -332,6 +332,235 @@ exaTryDriverSolidFill(PicturePtr pSrc, - } - - static int -+exaTryDriverCompositeRects(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects) -+{ -+ ExaScreenPriv (pDst->pDrawable->pScreen); -+ int src_off_x, src_off_y, dst_off_x, dst_off_y; -+ PixmapPtr pSrcPix, pDstPix; -+ ExaPixmapPrivPtr pSrcExaPix, pDstExaPix; -+ struct _Pixmap scratch; -+ ExaMigrationRec pixmaps[2]; -+ -+ if (!pExaScr->info->PrepareComposite) -+ return -1; -+ -+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); -+ pSrcExaPix = ExaGetPixmapPriv(pSrcPix); -+ -+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable); -+ pDstExaPix = ExaGetPixmapPriv(pDstPix); -+ -+ /* Check whether the accelerator can use these pixmaps. -+ * FIXME: If it cannot, use temporary pixmaps so that the drawing -+ * happens within limits. -+ */ -+ if (pSrcExaPix->accel_blocked || -+ pDstExaPix->accel_blocked) -+ { -+ return -1; -+ } -+ -+ if (pExaScr->info->CheckComposite && -+ !(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst)) -+ { -+ return -1; -+ } -+ -+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y); -+ -+ pixmaps[0].as_dst = TRUE; -+ pixmaps[0].as_src = exaOpReadsDestination(op); -+ pixmaps[0].pPix = pDstPix; -+ pixmaps[0].pReg = NULL; -+ pixmaps[1].as_dst = FALSE; -+ pixmaps[1].as_src = TRUE; -+ pixmaps[1].pPix = pSrcPix; -+ pixmaps[1].pReg = NULL; -+ exaDoMigration(pixmaps, 2, TRUE); -+ -+ pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y); -+ if (!exaPixmapIsOffscreen(pDstPix)) -+ return 0; -+ -+ if (!pSrcPix && pExaScr->info->UploadToScratch) -+ { -+ pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable); -+ if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch)) -+ pSrcPix = &scratch; -+ } -+ -+ if (!pSrcPix) -+ return 0; -+ -+ if (!(*pExaScr->info->PrepareComposite) (op, pSrc, NULL, pDst, pSrcPix, -+ NULL, pDstPix)) -+ return -1; -+ -+ while (nrect--) -+ { -+ INT16 xDst = rects->xDst + pDst->pDrawable->x; -+ INT16 yDst = rects->yDst + pDst->pDrawable->y; -+ INT16 xSrc = rects->xSrc + pSrc->pDrawable->x; -+ INT16 ySrc = rects->ySrc + pSrc->pDrawable->y; -+ -+ RegionRec region; -+ BoxPtr pbox; -+ int nbox; -+ -+ if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, -+ xSrc, ySrc, 0, 0, xDst, yDst, -+ rects->width, rects->height)) -+ goto next_rect; -+ -+ REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y); -+ -+ nbox = REGION_NUM_RECTS(®ion); -+ pbox = REGION_RECTS(®ion); -+ -+ xSrc = xSrc + src_off_x - xDst - dst_off_x; -+ ySrc = ySrc + src_off_y - yDst - dst_off_y; -+ -+ while (nbox--) -+ { -+ (*pExaScr->info->Composite) (pDstPix, -+ pbox->x1 + xSrc, -+ pbox->y1 + ySrc, -+ 0, 0, -+ pbox->x1, -+ pbox->y1, -+ pbox->x2 - pbox->x1, -+ pbox->y2 - pbox->y1); -+ pbox++; -+ } -+ -+ next_rect: -+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); -+ -+ rects++; -+ } -+ -+ (*pExaScr->info->DoneComposite) (pDstPix); -+ exaMarkSync(pDst->pDrawable->pScreen); -+ -+ return 1; -+} -+ -+/** -+ * Copy a number of rectangles from source to destination in a single -+ * operation. This is specialized for building a glyph mask: we don'y -+ * have a mask argument because we don't need it for that, and we -+ * don't have he special-case fallbacks found in exaComposite() - if the -+ * driver can support it, we use the driver functionality, otherwise we -+ * fallback straight to software. -+ */ -+void -+exaCompositeRects(CARD8 op, -+ PicturePtr pSrc, -+ PicturePtr pDst, -+ int nrect, -+ ExaCompositeRectPtr rects) -+{ -+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable); -+ ExaPixmapPriv(pPixmap); -+ RegionRec region; -+ int n; -+ ExaCompositeRectPtr r; -+ -+ if (pExaPixmap->pDamage) { -+ int xoff, yoff; -+ int x1 = MAXSHORT; -+ int y1 = MAXSHORT; -+ int x2 = MINSHORT; -+ int y2 = MINSHORT; -+ RegionPtr pending_damage; -+ BoxRec box; -+ -+ /* We have to manage the damage ourselves, since CompositeRects isn't -+ * something in the screen that can be managed by the damage extension, -+ * and EXA depends on damage to track what needs to be migrated between -+ * offscreen and onscreen. -+ */ -+ -+ /* Compute the overall extents of the composited region - we're making -+ * the assumption here that we are compositing a bunch of glyphs that -+ * cluster closely together and damaging each glyph individually would -+ * be a loss compared to damaging the bounding box. -+ */ -+ n = nrect; -+ r = rects; -+ while (n--) { -+ int rect_x2 = r->xDst + r->width; -+ int rect_y2 = r->yDst + r->width; -+ -+ if (r->xDst < x1) x1 = r->xDst; -+ if (r->xDst < y1) y1 = r->xDst; -+ if (rect_x2 > x2) x2 = rect_x2; -+ if (rect_y2 > y2) y2 = rect_y2; -+ -+ r++; -+ } -+ -+ if (x2 <= x1 && y2 <= y1) -+ return; -+ -+ box.x1 = x1; -+ box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT; -+ box.y1 = y1; -+ box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT; -+ -+ /* The pixmap migration code relies on pendingDamage indicating -+ * the bounds of the current rendering, so we need to force -+ * the actual damage into that region before we do anything, and -+ * (see use of DamagePendingRegion in exaCopyDirty) -+ */ -+ -+ REGION_INIT(pScreen, ®ion, &box, 1); -+ -+ exaGetDrawableDeltas(pDst->pDrawable, pPixmap, &xoff, &yoff); -+ -+ REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); -+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); -+ REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff); -+ } -+ -+ /************************************************************/ -+ -+ ValidatePicture (pSrc); -+ ValidatePicture (pDst); -+ -+ if (exaTryDriverCompositeRects(op, pSrc, pDst, nrect, rects) != 1) { -+ n = nrect; -+ r = rects; -+ while (n--) { -+ ExaCheckComposite (op, pSrc, NULL, pDst, -+ r->xSrc, r->ySrc, -+ 0, 0, -+ r->xDst, r->yDst, -+ r->width, r->height); -+ r++; -+ } -+ } -+ -+ /************************************************************/ -+ -+ if (pExaPixmap->pDamage) { -+ /* Now we have to flush the damage out from pendingDamage => damage -+ * Calling DamageDamageRegion has that effect. (We could pass -+ * in an empty region here, but we pass in the same region we -+ * use above; the effect is the same.) -+ */ -+ -+ DamageDamageRegion(pDst->pDrawable, ®ion); -+ REGION_UNINIT(pScreen, ®ion); -+ } -+} -+ -+static int - exaTryDriverComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, -@@ -842,23 +1071,26 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - DrawablePtr pDraw = pDst->pDrawable; - PixmapPtr pixmap = exaGetDrawablePixmap (pDraw); - ExaPixmapPriv (pixmap); -- RegionRec migration; -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- int xoff, yoff; - -- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); -+ if (pExaPixmap->pDamage) { -+ RegionRec migration; -+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ int xoff, yoff; -+ -+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); - -- xoff += pDraw->x; -- yoff += pDraw->y; -+ xoff += pDraw->x; -+ yoff += pDraw->y; - -- bounds.x1 += xoff; -- bounds.y1 += yoff; -- bounds.x2 += xoff; -- bounds.y2 += yoff; -+ bounds.x1 += xoff; -+ bounds.y1 += yoff; -+ bounds.x2 += xoff; -+ bounds.y2 += yoff; - -- REGION_INIT(pScreen, &migration, &bounds, 1); -- REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -- REGION_UNINIT(pScreen, &migration); -+ REGION_INIT(pScreen, &migration, &bounds, 1); -+ REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -+ REGION_UNINIT(pScreen, &migration); -+ } - - exaPrepareAccess(pDraw, EXA_PREPARE_DEST); - -@@ -945,23 +1177,26 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - DrawablePtr pDraw = pDst->pDrawable; - PixmapPtr pixmap = exaGetDrawablePixmap (pDraw); - ExaPixmapPriv (pixmap); -- RegionRec migration; -- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -- int xoff, yoff; - -- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); -+ if (pExaPixmap->pDamage) { -+ RegionRec migration; -+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); -+ int xoff, yoff; -+ -+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff); - -- xoff += pDraw->x; -- yoff += pDraw->y; -+ xoff += pDraw->x; -+ yoff += pDraw->y; - -- bounds.x1 += xoff; -- bounds.y1 += yoff; -- bounds.x2 += xoff; -- bounds.y2 += yoff; -+ bounds.x1 += xoff; -+ bounds.y1 += yoff; -+ bounds.x2 += xoff; -+ bounds.y2 += yoff; - -- REGION_INIT(pScreen, &migration, &bounds, 1); -- REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -- REGION_UNINIT(pScreen, &migration); -+ REGION_INIT(pScreen, &migration, &bounds, 1); -+ REGION_UNION(pScreen, pending_damage, pending_damage, &migration); -+ REGION_UNINIT(pScreen, &migration); -+ } - - exaPrepareAccess(pDraw, EXA_PREPARE_DEST); - (*ps->AddTriangles) (pDst, 0, 0, ntri, tris); -diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c -index d7bd06c..d5d6a30 100644 ---- a/exa/exa_unaccel.c -+++ b/exa/exa_unaccel.c -@@ -97,12 +97,15 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits) - { -+ ExaPixmapPriv(exaGetDrawablePixmap(pDrawable)); -+ - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, - pGC->alu)) - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - else -- ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST); -+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ? -+ DamagePendingRegion(pExaPixmap->pDamage) : NULL); - fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - } -@@ -350,20 +353,6 @@ ExaCheckComposite (CARD8 op, - REGION_UNINIT(pScreen, ®ion); - } - --void --ExaCheckAddTraps (PicturePtr pPicture, -- INT16 x_off, -- INT16 y_off, -- int ntrap, -- xTrap *traps) --{ -- EXA_FALLBACK(("to pict %p (%c)\n", -- exaDrawableLocation(pPicture->pDrawable))); -- exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); -- fbAddTraps (pPicture, x_off, y_off, ntrap, traps); -- exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); --} -- - /** - * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps - * that happen to be 1x1. Pixmap must be at least 8bpp. -@@ -373,23 +362,22 @@ ExaCheckAddTraps (PicturePtr pPicture, - CARD32 - exaGetPixmapFirstPixel (PixmapPtr pPixmap) - { -- ExaScreenPriv(pPixmap->drawable.pScreen); - CARD32 pixel; - void *fb; - Bool need_finish = FALSE; - BoxRec box; - RegionRec migration; - ExaPixmapPriv (pPixmap); -- Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box); -- Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, -- &box); -+ Bool sys_valid = pExaPixmap->pDamage && -+ !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box); -+ Bool damaged = pExaPixmap->pDamage && -+ miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box); - Bool offscreen = exaPixmapIsOffscreen(pPixmap); - - fb = pExaPixmap->sys_ptr; - - /* Try to avoid framebuffer readbacks */ -- if (pExaScr->info->CreatePixmap || -- (!offscreen && !sys_valid && !damaged) || -+ if ((!offscreen && !sys_valid && !damaged) || - (offscreen && (!sys_valid || damaged))) - { - box.x1 = 0; -diff --git a/hw/xfree86/exa/exa.man.pre b/hw/xfree86/exa/exa.man.pre -index 14859bc..31e1cfe 100644 ---- a/hw/xfree86/exa/exa.man.pre -+++ b/hw/xfree86/exa/exa.man.pre -@@ -31,12 +31,6 @@ Disables acceleration of downloading of pixmap data from the framebuffer. - Not usable with drivers which rely on DownloadFromScreen succeeding. - Default: No. - .TP --.BI "Option \*qEXAOptimizeMigration\*q \*q" boolean \*q --Enables an additional optimization for migration of destination pixmaps. This --may improve performance in some cases (e.g. when switching virtual desktops with --no compositing manager) but causes corruption in others (e.g. when starting --compiz). Default: No. --.TP - .BI "Option \*qMigrationHeuristic\*q \*q" anystr \*q - Chooses an alternate pixmap migration heuristic, for debugging purposes. The - default is intended to be the best performing one for general use, though others -diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c -index e18da0a..4a8d8f2 100644 ---- a/hw/xfree86/exa/examodule.c -+++ b/hw/xfree86/exa/examodule.c -@@ -145,7 +145,7 @@ exaDDXDriverInit(ScreenPtr pScreen) - pExaScr->optimize_migration = - xf86ReturnOptValBool(pScreenPriv->options, - EXAOPT_OPTIMIZE_MIGRATION, -- FALSE); -+ TRUE); - } - - if (xf86ReturnOptValBool(pScreenPriv->options, -@@ -179,13 +179,6 @@ exaDDXDriverInit(ScreenPtr pScreen) - - } - --/*ARGSUSED*/ --static const OptionInfoRec * --EXAAvailableOptions(void *unused) --{ -- return (EXAOptions); --} -- - static XF86ModuleVersionInfo exaVersRec = - { - "exa", --- -1.5.5.1 - diff --git a/xserver-1.5.0-enable-selinux.patch b/xserver-1.5.0-enable-selinux.patch deleted file mode 100644 index 3fa5cdd..0000000 --- a/xserver-1.5.0-enable-selinux.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 79fefef30f94f979a8f69ce9253d08be4b28a543 Mon Sep 17 00:00:00 2001 -From: Adam Jackson -Date: Wed, 13 Aug 2008 13:42:31 -0400 -Subject: [PATCH] Enable selinux extension again. - ---- - os/utils.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/os/utils.c b/os/utils.c -index f58c763..d785d46 100644 ---- a/os/utils.c -+++ b/os/utils.c -@@ -233,7 +233,7 @@ _X_EXPORT Bool noXInputExtension = FALSE; - _X_EXPORT Bool noXIdleExtension = FALSE; - #endif - #ifdef XSELINUX --_X_EXPORT Bool noSELinuxExtension = TRUE; -+_X_EXPORT Bool noSELinuxExtension = FALSE; - _X_EXPORT int selinuxEnforcingState = SELINUX_MODE_DEFAULT; - #endif - #ifdef XV --- -1.5.5.1 - diff --git a/xserver-1.5.0-no-evdev-keyboards-kthnx.patch b/xserver-1.5.0-no-evdev-keyboards-kthnx.patch deleted file mode 100644 index fa368bd..0000000 --- a/xserver-1.5.0-no-evdev-keyboards-kthnx.patch +++ /dev/null @@ -1,58 +0,0 @@ -From e654ed62d44b8d61484f97eab1b1adbfb08d375f Mon Sep 17 00:00:00 2001 -From: Dave Airlie -Date: Thu, 12 Jun 2008 11:52:29 +1000 -Subject: [PATCH] config: disable evdev for keyboards - ---- - config/hal.c | 28 ++++++++++++++++++++++++++++ - 1 files changed, 28 insertions(+), 0 deletions(-) - -diff --git a/config/hal.c b/config/hal.c -index f4eb438..ee0f18f 100644 ---- a/config/hal.c -+++ b/config/hal.c -@@ -168,6 +168,31 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) - } - #endif - -+static Bool -+get_device_is_keyboard(LibHalContext *hal_ctx, const char *udi, DBusError *error_p) -+{ -+ char **props; -+ int i; -+ Bool ret = FALSE; -+ -+ props = libhal_device_get_property_strlist(hal_ctx, udi, -+ "info.capabilities", error_p); -+ if (!props) { -+ return FALSE; -+ } -+ for (i = 0; props[i]; i++) { -+ if (strcmp(props[i], "input.keys") == 0 || -+ strcmp(props[i], "input.keyboard") == 0) { -+ ret = TRUE; -+ goto out_error; -+ } -+ } -+ -+out_error: -+ libhal_free_string_array(props); -+ return ret; -+} -+ - static void - device_added(LibHalContext *hal_ctx, const char *udi) - { -@@ -184,6 +209,9 @@ device_added(LibHalContext *hal_ctx, const char *udi) - - dbus_error_init(&error); - -+ if (get_device_is_keyboard(hal_ctx, udi, &error)) -+ goto unwind; -+ - driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); - if (!driver){ - /* verbose, don't tell the user unless they _want_ to see it */ --- -1.5.3.7 - diff --git a/xserver-1.5.0-xkb-fix-ProcXkbSetXYZ-to-work-on-all.patch b/xserver-1.5.0-xkb-fix-ProcXkbSetXYZ-to-work-on-all.patch deleted file mode 100644 index 13e197a..0000000 --- a/xserver-1.5.0-xkb-fix-ProcXkbSetXYZ-to-work-on-all.patch +++ /dev/null @@ -1,2245 +0,0 @@ -From 6d1201b05ed61aec508d5d9f88e3a2d33be39849 Mon Sep 17 00:00:00 2001 -From: Peter Hutterer -Date: Thu, 31 Jul 2008 16:03:21 +0930 -Subject: [PATCH] xkb: fix up ProcXkbSetXYZ to work on all core devices. - -Simple principle: if the client requests an xkb change on the core keyboard, -apply the same change to all core-sending keyboard devices. This way, if you -change the layout on the VCK, you get the same layout on all devices. - -That's the theory anyway, the implementation makes you want to gauge your eyes -out. ---- - xkb/xkb.c | 1880 +++++++++++++++++++++++++++++++++++++++---------------------- - 1 files changed, 1210 insertions(+), 670 deletions(-) - -diff --git a/xkb/xkb.c b/xkb/xkb.c -index 07f57a7..cc2f77c 100644 ---- a/xkb/xkb.c -+++ b/xkb/xkb.c -@@ -24,6 +24,31 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. - - ********************************************************/ - -+/* Copyright © 2008 Red Hat, Inc. -+ -+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 (including the next -+paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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. -+ -+Authors: Peter Hutterer -+ -+*/ -+ - #ifdef HAVE_DIX_CONFIG_H - #include - #endif -@@ -348,17 +373,119 @@ ProcXkbSelectEvents(ClientPtr client) - } - - /***====================================================================***/ -+/** -+ * Ring a bell on the given device for the given client. -+ */ -+static int -+_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, -+ int bellClass, int bellID, int pitch, int duration, -+ int percent, int forceSound, int eventOnly, Atom name) -+{ -+ int base; -+ pointer ctrl; -+ int oldPitch, oldDuration; -+ int newPercent; -+ -+ if (bellClass == KbdFeedbackClass) { -+ KbdFeedbackPtr k; -+ if (bellID==XkbDfltXIId) -+ k= dev->kbdfeed; -+ else { -+ for (k=dev->kbdfeed; k; k=k->next) { -+ if (k->ctrl.id == bellID) -+ break; -+ } -+ } -+ if (!k) { -+ client->errorValue = _XkbErrCode2(0x5,bellID); -+ return BadValue; -+ } -+ base = k->ctrl.bell; -+ ctrl = (pointer) &(k->ctrl); -+ oldPitch= k->ctrl.bell_pitch; -+ oldDuration= k->ctrl.bell_duration; -+ if (pitch!=0) { -+ if (pitch==-1) -+ k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; -+ else k->ctrl.bell_pitch= pitch; -+ } -+ if (duration!=0) { -+ if (duration==-1) -+ k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; -+ else k->ctrl.bell_duration= duration; -+ } -+ } -+ else if (bellClass == BellFeedbackClass) { -+ BellFeedbackPtr b; -+ if (bellID==XkbDfltXIId) -+ b= dev->bell; -+ else { -+ for (b=dev->bell; b; b=b->next) { -+ if (b->ctrl.id == bellID) -+ break; -+ } -+ } -+ if (!b) { -+ client->errorValue = _XkbErrCode2(0x6,bellID); -+ return BadValue; -+ } -+ base = b->ctrl.percent; -+ ctrl = (pointer) &(b->ctrl); -+ oldPitch= b->ctrl.pitch; -+ oldDuration= b->ctrl.duration; -+ if (pitch!=0) { -+ if (pitch==-1) -+ b->ctrl.pitch= defaultKeyboardControl.bell_pitch; -+ else b->ctrl.pitch= pitch; -+ } -+ if (duration!=0) { -+ if (duration==-1) -+ b->ctrl.duration= defaultKeyboardControl.bell_duration; -+ else b->ctrl.duration= duration; -+ } -+ } -+ else { -+ client->errorValue = _XkbErrCode2(0x7, bellClass);; -+ return BadValue; -+ } -+ -+ newPercent = (base * percent)/100; -+ if (percent < 0) -+ newPercent = base + newPercent; -+ else newPercent = base - newPercent + percent; -+ -+ XkbHandleBell(forceSound, eventOnly, -+ dev, newPercent, ctrl, bellClass, -+ name, pWin, client); -+ if ((pitch!=0)||(duration!=0)) { -+ if (bellClass == KbdFeedbackClass) { -+ KbdFeedbackPtr k; -+ k= (KbdFeedbackPtr)ctrl; -+ if (pitch!=0) -+ k->ctrl.bell_pitch= oldPitch; -+ if (duration!=0) -+ k->ctrl.bell_duration= oldDuration; -+ } -+ else { -+ BellFeedbackPtr b; -+ b= (BellFeedbackPtr)ctrl; -+ if (pitch!=0) -+ b->ctrl.pitch= oldPitch; -+ if (duration!=0) -+ b->ctrl.duration= oldDuration; -+ } -+ } -+ -+ return Success; -+} - --/* FIXME: Needs to ding on all core-sending devices. */ - int - ProcXkbBell(ClientPtr client) - { - REQUEST(xkbBellReq); - DeviceIntPtr dev; - WindowPtr pWin; -- int rc, base; -- int newPercent,oldPitch,oldDuration; -- pointer ctrl; -+ int rc; - - REQUEST_SIZE_MATCH(xkbBellReq); - -@@ -368,6 +495,7 @@ ProcXkbBell(ClientPtr client) - CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); - CHK_ATOM_OR_NONE(stuff->name); - -+ /* device-independent checks request for sane values */ - if ((stuff->forceSound)&&(stuff->eventOnly)) { - client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); - return BadMatch; -@@ -390,68 +518,7 @@ ProcXkbBell(ClientPtr client) - stuff->bellClass= KbdFeedbackClass; - else stuff->bellClass= BellFeedbackClass; - } -- if (stuff->bellClass == KbdFeedbackClass) { -- KbdFeedbackPtr k; -- if (stuff->bellID==XkbDfltXIId) -- k= dev->kbdfeed; -- else { -- for (k=dev->kbdfeed; k; k=k->next) { -- if (k->ctrl.id == stuff->bellID) -- break; -- } -- } -- if (!k) { -- client->errorValue= _XkbErrCode2(0x5,stuff->bellID); -- return BadValue; -- } -- base = k->ctrl.bell; -- ctrl = (pointer) &(k->ctrl); -- oldPitch= k->ctrl.bell_pitch; -- oldDuration= k->ctrl.bell_duration; -- if (stuff->pitch!=0) { -- if (stuff->pitch==-1) -- k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; -- else k->ctrl.bell_pitch= stuff->pitch; -- } -- if (stuff->duration!=0) { -- if (stuff->duration==-1) -- k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; -- else k->ctrl.bell_duration= stuff->duration; -- } -- } -- else if (stuff->bellClass == BellFeedbackClass) { -- BellFeedbackPtr b; -- if (stuff->bellID==XkbDfltXIId) -- b= dev->bell; -- else { -- for (b=dev->bell; b; b=b->next) { -- if (b->ctrl.id == stuff->bellID) -- break; -- } -- } -- if (!b) { -- client->errorValue = _XkbErrCode2(0x6,stuff->bellID); -- return BadValue; -- } -- base = b->ctrl.percent; -- ctrl = (pointer) &(b->ctrl); -- oldPitch= b->ctrl.pitch; -- oldDuration= b->ctrl.duration; -- if (stuff->pitch!=0) { -- if (stuff->pitch==-1) -- b->ctrl.pitch= defaultKeyboardControl.bell_pitch; -- else b->ctrl.pitch= stuff->pitch; -- } -- if (stuff->duration!=0) { -- if (stuff->duration==-1) -- b->ctrl.duration= defaultKeyboardControl.bell_duration; -- else b->ctrl.duration= stuff->duration; -- } -- } -- else { -- client->errorValue = _XkbErrCode2(0x7,stuff->bellClass);; -- return BadValue; -- } -+ - if (stuff->window!=None) { - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) { -@@ -461,32 +528,39 @@ ProcXkbBell(ClientPtr client) - } - else pWin= NULL; - -- newPercent= (base*stuff->percent)/100; -- if (stuff->percent < 0) -- newPercent= base+newPercent; -- else newPercent= base-newPercent+stuff->percent; -- XkbHandleBell(stuff->forceSound, stuff->eventOnly, -- dev, newPercent, ctrl, stuff->bellClass, -- stuff->name, pWin, client); -- if ((stuff->pitch!=0)||(stuff->duration!=0)) { -- if (stuff->bellClass == KbdFeedbackClass) { -- KbdFeedbackPtr k; -- k= (KbdFeedbackPtr)ctrl; -- if (stuff->pitch!=0) -- k->ctrl.bell_pitch= oldPitch; -- if (stuff->duration!=0) -- k->ctrl.bell_duration= oldDuration; -- } -- else { -- BellFeedbackPtr b; -- b= (BellFeedbackPtr)ctrl; -- if (stuff->pitch!=0) -- b->ctrl.pitch= oldPitch; -- if (stuff->duration!=0) -- b->ctrl.duration= oldDuration; -- } -+ /* Client wants to ring a bell on the core keyboard? -+ Ring the bell on the core keyboard (which does nothing, but if that -+ fails the client is screwed anyway), and then on all extension devices. -+ Fail if the core keyboard fails but not the extension devices. this -+ may cause some keyboards to ding and others to stay silent. Fix -+ your client to use explicit keyboards to avoid this. -+ -+ dev is the device the client requested. -+ */ -+ rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, -+ stuff->pitch, stuff->duration, stuff->percent, -+ stuff->forceSound, stuff->eventOnly, stuff->name); -+ -+ if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || -+ (stuff->deviceSpec == XkbUseCorePtr))) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); -+ if (rc == Success) -+ _XkbBell(client, other, pWin, stuff->bellClass, -+ stuff->bellID, stuff->pitch, stuff->duration, -+ stuff->percent, stuff->forceSound, -+ stuff->eventOnly, stuff->name); -+ } -+ } -+ rc = Success; /* reset to success, that's what we got for the VCK */ - } -- return Success; -+ -+ return rc; - } - - /***====================================================================***/ -@@ -2283,158 +2357,165 @@ XkbServerMapPtr srv = xkbi->desc->server; - return (char *)wire; - } - --/* FIXME: Needs to set map on all core-sending devices. */ --int --ProcXkbSetMap(ClientPtr client) -+/** -+ * Check if the given request can be applied to the given device but don't -+ * actually do anything.. -+ */ -+static int -+_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values) - { -- DeviceIntPtr dev; -- XkbSrvInfoPtr xkbi; -- XkbDescPtr xkb; -- XkbChangesRec change; -- XkbEventCauseRec cause; -- int nTypes = 0,nActions,error; -- char * tmp; -- CARD8 mapWidths[XkbMaxLegalKeyCode+1]; -- CARD16 symsPerKey[XkbMaxLegalKeyCode+1]; -- Bool sentNKN; -- -- REQUEST(xkbSetMapReq); -- REQUEST_AT_LEAST_SIZE(xkbSetMapReq); -- -- if (!(client->xkbClientFlags&_XkbClientInitialized)) -- return BadAccess; -- -- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -- CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); -+ XkbSrvInfoPtr xkbi; -+ XkbDescPtr xkb; -+ int error; -+ int nTypes = 0, nActions; -+ CARD8 mapWidths[XkbMaxLegalKeyCode + 1]; -+ CARD16 symsPerKey[XkbMaxLegalKeyCode + 1]; - -- XkbSetCauseXkbReq(&cause,X_kbSetMap,client); - xkbi= dev->key->xkbInfo; - xkb = xkbi->desc; - -- if ((xkb->min_key_code!=stuff->minKeyCode)|| -- (xkb->max_key_code!=stuff->maxKeyCode)) { -+ if ((xkb->min_key_code != req->minKeyCode)|| -+ (xkb->max_key_code != req->maxKeyCode)) { - if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ -- stuff->minKeyCode= xkb->min_key_code; -- stuff->maxKeyCode= xkb->max_key_code; -+ req->minKeyCode= xkb->min_key_code; -+ req->maxKeyCode= xkb->max_key_code; - } - else { -- if (!XkbIsLegalKeycode(stuff->minKeyCode)) { -- client->errorValue= _XkbErrCode3(2,stuff->minKeyCode, -- stuff->maxKeyCode); -+ if (!XkbIsLegalKeycode(req->minKeyCode)) { -+ client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); - return BadValue; - } -- if (stuff->minKeyCode>stuff->maxKeyCode) { -- client->errorValue= _XkbErrCode3(3,stuff->minKeyCode, -- stuff->maxKeyCode); -+ if (req->minKeyCode > req->maxKeyCode) { -+ client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); - return BadMatch; - } - } - } - -- tmp = (char *)&stuff[1]; -- if ((stuff->present&XkbKeyTypesMask)&& -- (!CheckKeyTypes(client,xkb,stuff,(xkbKeyTypeWireDesc **)&tmp, -+ if ((req->present & XkbKeyTypesMask) && -+ (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values, - &nTypes,mapWidths))) { - client->errorValue = nTypes; - return BadValue; - } -- if ((stuff->present&XkbKeySymsMask)&& -- (!CheckKeySyms(client,xkb,stuff,nTypes,mapWidths,symsPerKey, -- (xkbSymMapWireDesc **)&tmp,&error))) { -+ if ((req->present & XkbKeySymsMask) && -+ (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey, -+ (xkbSymMapWireDesc **)&values,&error))) { - client->errorValue = error; - return BadValue; - } - -- if ((stuff->present&XkbKeyActionsMask)&& -- (!CheckKeyActions(xkb,stuff,nTypes,mapWidths,symsPerKey, -- (CARD8 **)&tmp,&nActions))) { -+ if ((req->present & XkbKeyActionsMask) && -+ (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey, -+ (CARD8 **)&values,&nActions))) { - client->errorValue = nActions; - return BadValue; - } - -- if ((stuff->present&XkbKeyBehaviorsMask)&& -- (!CheckKeyBehaviors(xkb,stuff,(xkbBehaviorWireDesc**)&tmp,&error))) { -+ if ((req->present & XkbKeyBehaviorsMask) && -+ (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) { - client->errorValue = error; - return BadValue; - } - -- if ((stuff->present&XkbVirtualModsMask)&& -- (!CheckVirtualMods(xkb,stuff,(CARD8 **)&tmp,&error))) { -+ if ((req->present & XkbVirtualModsMask) && -+ (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } -- if ((stuff->present&XkbExplicitComponentsMask)&& -- (!CheckKeyExplicit(xkb,stuff,(CARD8 **)&tmp,&error))) { -+ if ((req->present&XkbExplicitComponentsMask) && -+ (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } -- if ((stuff->present&XkbModifierMapMask)&& -- (!CheckModifierMap(xkb,stuff,(CARD8 **)&tmp,&error))) { -+ if ((req->present&XkbModifierMapMask) && -+ (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } -- if ((stuff->present&XkbVirtualModMapMask)&& -- (!CheckVirtualModMap(xkb,stuff,(xkbVModMapWireDesc **)&tmp,&error))) { -+ if ((req->present&XkbVirtualModMapMask) && -+ (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) { - client->errorValue= error; - return BadValue; - } -- if (((tmp-((char *)stuff))/4)!=stuff->length) { -+ -+ if (((values-((char *)req))/4)!= req->length) { - ErrorF("Internal error! Bad length in XkbSetMap (after check)\n"); -- client->errorValue = tmp-((char *)&stuff[1]); -+ client->errorValue = values-((char *)&req[1]); - return BadLength; - } -- bzero(&change,sizeof(change)); -- sentNKN= False; -- if ((xkb->min_key_code!=stuff->minKeyCode)|| -- (xkb->max_key_code!=stuff->maxKeyCode)) { -+ -+ return Success; -+} -+ -+/** -+ * Apply the given request on the given device. -+ */ -+static int -+_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values) -+{ -+ XkbEventCauseRec cause; -+ XkbChangesRec change; -+ Bool sentNKN; -+ XkbSrvInfoPtr xkbi; -+ XkbDescPtr xkb; -+ -+ xkbi= dev->key->xkbInfo; -+ xkb = xkbi->desc; -+ -+ XkbSetCauseXkbReq(&cause,X_kbSetMap,client); -+ bzero(&change, sizeof(change)); -+ sentNKN = False; -+ if ((xkb->min_key_code!=req->minKeyCode)|| -+ (xkb->max_key_code!=req->maxKeyCode)) { - Status status; - xkbNewKeyboardNotify nkn; -- nkn.deviceID= nkn.oldDeviceID= dev->id; -- nkn.oldMinKeyCode= xkb->min_key_code; -- nkn.oldMaxKeyCode= xkb->max_key_code; -- status= XkbChangeKeycodeRange(xkb,stuff->minKeyCode,stuff->maxKeyCode, -- &change); -- if (status!=Success) -- return status; -- nkn.minKeyCode= xkb->min_key_code; -- nkn.maxKeyCode= xkb->max_key_code; -- nkn.requestMajor= XkbReqCode; -- nkn.requestMinor= X_kbSetMap; -- nkn.changed= XkbNKN_KeycodesMask; -+ nkn.deviceID = nkn.oldDeviceID = dev->id; -+ nkn.oldMinKeyCode = xkb->min_key_code; -+ nkn.oldMaxKeyCode = xkb->max_key_code; -+ status= XkbChangeKeycodeRange(xkb, req->minKeyCode, -+ req->maxKeyCode, &change); -+ if (status != Success) -+ return status; /* oh-oh. what about the other keyboards? */ -+ nkn.minKeyCode = xkb->min_key_code; -+ nkn.maxKeyCode = xkb->max_key_code; -+ nkn.requestMajor = XkbReqCode; -+ nkn.requestMinor = X_kbSetMap; -+ nkn.changed = XkbNKN_KeycodesMask; - XkbSendNewKeyboardNotify(dev,&nkn); -- sentNKN= True; -- } -- tmp = (char *)&stuff[1]; -- if (stuff->present&XkbKeyTypesMask) { -- tmp = SetKeyTypes(xkb,stuff,(xkbKeyTypeWireDesc *)tmp,&change); -- if (!tmp) goto allocFailure; -- } -- if (stuff->present&XkbKeySymsMask) { -- tmp = SetKeySyms(client,xkb,stuff,(xkbSymMapWireDesc *)tmp,&change,dev); -- if (!tmp) goto allocFailure; -- } -- if (stuff->present&XkbKeyActionsMask) { -- tmp = SetKeyActions(xkb,stuff,(CARD8 *)tmp,&change); -- if (!tmp) goto allocFailure; -- } -- if (stuff->present&XkbKeyBehaviorsMask) { -- tmp= SetKeyBehaviors(xkbi,stuff,(xkbBehaviorWireDesc *)tmp,&change); -- if (!tmp) goto allocFailure; -- } -- if (stuff->present&XkbVirtualModsMask) -- tmp= SetVirtualMods(xkbi,stuff,(CARD8 *)tmp,&change); -- if (stuff->present&XkbExplicitComponentsMask) -- tmp= SetKeyExplicit(xkbi,stuff,(CARD8 *)tmp,&change); -- if (stuff->present&XkbModifierMapMask) -- tmp= SetModifierMap(xkbi,stuff,(CARD8 *)tmp,&change); -- if (stuff->present&XkbVirtualModMapMask) -- tmp= SetVirtualModMap(xkbi,stuff,(xkbVModMapWireDesc *)tmp,&change); -- if (((tmp-((char *)stuff))/4)!=stuff->length) { -+ sentNKN = True; -+ } -+ -+ if (req->present&XkbKeyTypesMask) { -+ values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change); -+ if (!values) goto allocFailure; -+ } -+ if (req->present&XkbKeySymsMask) { -+ values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev); -+ if (!values) goto allocFailure; -+ } -+ if (req->present&XkbKeyActionsMask) { -+ values = SetKeyActions(xkb,req,(CARD8 *)values,&change); -+ if (!values) goto allocFailure; -+ } -+ if (req->present&XkbKeyBehaviorsMask) { -+ values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change); -+ if (!values) goto allocFailure; -+ } -+ if (req->present&XkbVirtualModsMask) -+ values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change); -+ if (req->present&XkbExplicitComponentsMask) -+ values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change); -+ if (req->present&XkbModifierMapMask) -+ values= SetModifierMap(xkbi,req,(CARD8 *)values,&change); -+ if (req->present&XkbVirtualModMapMask) -+ values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change); -+ if (((values-((char *)req))/4)!=req->length) { - ErrorF("Internal error! Bad length in XkbSetMap (after set)\n"); -- client->errorValue = tmp-((char *)&stuff[1]); -+ client->errorValue = values-((char *)&req[1]); - return BadLength; - } -- if (stuff->flags&XkbSetMapRecomputeActions) { -+ if (req->flags&XkbSetMapRecomputeActions) { - KeyCode first,last,firstMM,lastMM; - if (change.map.num_key_syms>0) { - first= change.map.first_key_sym; -@@ -2467,11 +2548,82 @@ ProcXkbSetMap(ClientPtr client) - XkbSendNotification(dev,&change,&cause); - - XkbUpdateCoreDescription(dev,False); -- return client->noClientException; -+ return Success; - allocFailure: - return BadAlloc; - } - -+ -+int -+ProcXkbSetMap(ClientPtr client) -+{ -+ DeviceIntPtr dev; -+ char * tmp; -+ int rc; -+ -+ REQUEST(xkbSetMapReq); -+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq); -+ -+ if (!(client->xkbClientFlags&_XkbClientInitialized)) -+ return BadAccess; -+ -+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -+ CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); -+ -+ tmp = (char *)&stuff[1]; -+ -+ /* Check if we can to the SetMap on the requested device. If this -+ succeeds, do the same thing for all extension devices (if needed). -+ If any of them fails, fail. */ -+ rc = _XkbSetMapChecks(client, dev, stuff, tmp); -+ -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ rc = _XkbSetMapChecks(client, other, stuff, tmp); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } -+ } -+ -+ /* We know now that we will succed with the SetMap. In theory anyway. */ -+ rc = _XkbSetMap(client, dev, stuff, tmp); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ _XkbSetMap(client, other, stuff, tmp); -+ /* ignore rc. if the SetMap failed although the check above -+ reported true there isn't much we can do. we still need to -+ set all other devices, hoping that at least they stay in -+ sync. */ -+ } -+ } -+ } -+ -+ return client->noClientException; -+} -+ - /***====================================================================***/ - - static Status -@@ -2600,57 +2752,58 @@ ProcXkbGetCompatMap(ClientPtr client) - return XkbSendCompatMap(client,compat,&rep); - } - --/* FIXME: Needs to set compat map on all core-sending devices. */ --int --ProcXkbSetCompatMap(ClientPtr client) -+/** -+ * Apply the given request on the given device. -+ * If dryRun is True, then value checks are performed, but the device isn't -+ * modified. -+ */ -+static int -+_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, -+ xkbSetCompatMapReq *req, char* data, BOOL dryRun) - { -- DeviceIntPtr dev; -- XkbSrvInfoPtr xkbi; -- XkbDescPtr xkb; -- XkbCompatMapPtr compat; -- char * data; -- int nGroups; -- register unsigned i,bit; -+ XkbSrvInfoPtr xkbi; -+ XkbDescPtr xkb; -+ XkbCompatMapPtr compat; -+ int nGroups; -+ unsigned i,bit; - -- REQUEST(xkbSetCompatMapReq); -- REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); -- -- if (!(client->xkbClientFlags&_XkbClientInitialized)) -- return BadAccess; -- -- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -- -- data = (char *)&stuff[1]; - xkbi = dev->key->xkbInfo; -- xkb= xkbi->desc; -- compat= xkb->compat; -- if ((stuff->nSI>0)||(stuff->truncateSI)) { -+ xkb = xkbi->desc; -+ compat = xkb->compat; -+ -+ if ((req->nSI>0)||(req->truncateSI)) { - xkbSymInterpretWireDesc *wire; -- if (stuff->firstSI>compat->num_si) { -+ if (req->firstSI>compat->num_si) { - client->errorValue = _XkbErrCode2(0x02,compat->num_si); - return BadValue; - } - wire= (xkbSymInterpretWireDesc *)data; -- wire+= stuff->nSI; -+ wire+= req->nSI; - data = (char *)wire; - } -+ - nGroups= 0; -- if (stuff->groups!=0) { -+ if (req->groups!=0) { - for (i=0,bit=1;igroups&bit ) -+ if ( req->groups&bit ) - nGroups++; - } - } - data+= nGroups*SIZEOF(xkbModsWireDesc); -- if (((data-((char *)stuff))/4)!=stuff->length) { -+ if (((data-((char *)req))/4)!=req->length) { - return BadLength; - } -- data = (char *)&stuff[1]; -- if (stuff->nSI>0) { -+ -+ /* Done all the checks we can do */ -+ if (dryRun) -+ return Success; -+ -+ data = (char *)&req[1]; -+ if (req->nSI>0) { - xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; - XkbSymInterpretPtr sym; -- if ((unsigned)(stuff->firstSI+stuff->nSI)>compat->num_si) { -- compat->num_si= stuff->firstSI+stuff->nSI; -+ if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) { -+ compat->num_si= req->firstSI+req->nSI; - compat->sym_interpret= _XkbTypedRealloc(compat->sym_interpret, - compat->num_si, - XkbSymInterpretRec); -@@ -2659,13 +2812,13 @@ ProcXkbSetCompatMap(ClientPtr client) - return BadAlloc; - } - } -- else if (stuff->truncateSI) { -- compat->num_si = stuff->firstSI+stuff->nSI; -+ else if (req->truncateSI) { -+ compat->num_si = req->firstSI+req->nSI; - } -- sym = &compat->sym_interpret[stuff->firstSI]; -- for (i=0;inSI;i++,wire++,sym++) { -+ sym = &compat->sym_interpret[req->firstSI]; -+ for (i=0;inSI;i++,wire++,sym++) { - if (client->swapped) { -- register int n; -+ int n; - swapl(&wire->sym,n); - } - sym->sym= wire->sym; -@@ -2674,21 +2827,21 @@ ProcXkbSetCompatMap(ClientPtr client) - sym->flags= wire->flags; - sym->virtual_mod= wire->virtualMod; - memcpy((char *)&sym->act,(char *)&wire->act, -- SIZEOF(xkbActionWireDesc)); -+ SIZEOF(xkbActionWireDesc)); - } - data = (char *)wire; - } -- else if (stuff->truncateSI) { -- compat->num_si = stuff->firstSI; -+ else if (req->truncateSI) { -+ compat->num_si = req->firstSI; - } - -- if (stuff->groups!=0) { -- register unsigned i,bit; -+ if (req->groups!=0) { -+ unsigned i, bit; - xkbModsWireDesc *wire = (xkbModsWireDesc *)data; -- for (i=0,bit=1;igroups&bit) { -+ for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { -+ if (req->groups & bit) { - if (client->swapped) { -- register int n; -+ int n; - swaps(&wire->virtualMods,n); - } - compat->groups[i].mask= wire->realMods; -@@ -2704,23 +2857,23 @@ ProcXkbSetCompatMap(ClientPtr client) - } - } - } -- i= XkbPaddedSize((data-((char *)stuff))); -- if ((i/4)!=stuff->length) { -- ErrorF("Internal length error on read in ProcXkbSetCompatMap\n"); -+ i= XkbPaddedSize((data-((char *)req))); -+ if ((i/4)!=req->length) { -+ ErrorF("Internal length error on read in _XkbSetCompatMap\n"); - return BadLength; - } -- -+ - if (dev->xkb_interest) { - xkbCompatMapNotify ev; - ev.deviceID = dev->id; -- ev.changedGroups = stuff->groups; -- ev.firstSI = stuff->firstSI; -- ev.nSI = stuff->nSI; -+ ev.changedGroups = req->groups; -+ ev.firstSI = req->firstSI; -+ ev.nSI = req->nSI; - ev.nTotalSI = compat->num_si; - XkbSendCompatMapNotify(dev,&ev); - } - -- if (stuff->recomputeActions) { -+ if (req->recomputeActions) { - XkbChangesRec change; - unsigned check; - XkbEventCauseRec cause; -@@ -2734,6 +2887,71 @@ ProcXkbSetCompatMap(ClientPtr client) - XkbUpdateCoreDescription(dev,False); - XkbSendNotification(dev,&change,&cause); - } -+ return Success; -+} -+ -+int -+ProcXkbSetCompatMap(ClientPtr client) -+{ -+ DeviceIntPtr dev; -+ char *data; -+ int rc; -+ -+ REQUEST(xkbSetCompatMapReq); -+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); -+ -+ if (!(client->xkbClientFlags&_XkbClientInitialized)) -+ return BadAccess; -+ -+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -+ -+ data = (char *)&stuff[1]; -+ -+ /* check first using a dry-run */ -+ rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); -+ if (rc != Success) -+ return rc; -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ /* dry-run */ -+ rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } -+ } -+ -+ /* Yay, the dry-runs succeed. Let's apply */ -+ rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); -+ if (rc != Success) -+ return rc; -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } -+ } -+ - return client->noClientException; - } - -@@ -2878,17 +3096,59 @@ XkbIndicatorPtr leds; - return XkbSendIndicatorMap(client,leds,&rep); - } - --/* FIXME: Needs to set indicator map on all core-sending devices. */ -+/** -+ * Apply the given map to the given device. Which specifies which components -+ * to apply. -+ */ -+static int -+_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, -+ int which, xkbIndicatorMapWireDesc *desc) -+{ -+ XkbSrvInfoPtr xkbi; -+ XkbSrvLedInfoPtr sli; -+ XkbEventCauseRec cause; -+ int i, bit; -+ -+ xkbi = dev->key->xkbInfo; -+ -+ sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, -+ XkbXI_IndicatorMapsMask); -+ if (!sli) -+ return BadAlloc; -+ -+ for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { -+ if (which & bit) { -+ sli->maps[i].flags = desc->flags; -+ sli->maps[i].which_groups = desc->whichGroups; -+ sli->maps[i].groups = desc->groups; -+ sli->maps[i].which_mods = desc->whichMods; -+ sli->maps[i].mods.mask = desc->mods; -+ sli->maps[i].mods.real_mods = desc->mods; -+ sli->maps[i].mods.vmods= desc->virtualMods; -+ sli->maps[i].ctrls = desc->ctrls; -+ if (desc->virtualMods!=0) { -+ unsigned tmp; -+ tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods); -+ sli->maps[i].mods.mask= desc->mods|tmp; -+ } -+ desc++; -+ } -+ } -+ -+ XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); -+ XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause); -+ -+ return Success; -+} -+ - int - ProcXkbSetIndicatorMap(ClientPtr client) - { -- register int i,bit; -- int nIndicators; -- DeviceIntPtr dev; -- XkbSrvInfoPtr xkbi; -- xkbIndicatorMapWireDesc *from; -- XkbSrvLedInfoPtr sli; -- XkbEventCauseRec cause; -+ int i, bit; -+ int nIndicators; -+ DeviceIntPtr dev; -+ xkbIndicatorMapWireDesc *from; -+ int rc; - - REQUEST(xkbSetIndicatorMapReq); - REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); -@@ -2898,8 +3158,6 @@ ProcXkbSetIndicatorMap(ClientPtr client) - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); - -- xkbi= dev->key->xkbInfo; -- - if (stuff->which==0) - return client->noClientException; - -@@ -2912,16 +3170,11 @@ ProcXkbSetIndicatorMap(ClientPtr client) - return BadLength; - } - -- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, -- XkbXI_IndicatorMapsMask); -- if (!sli) -- return BadAlloc; -- - from = (xkbIndicatorMapWireDesc *)&stuff[1]; - for (i=0,bit=1;iwhich&bit) { - if (client->swapped) { -- register int n; -+ int n; - swaps(&from->virtualMods,n); - swapl(&from->ctrls,n); - } -@@ -2932,28 +3185,25 @@ ProcXkbSetIndicatorMap(ClientPtr client) - } - - from = (xkbIndicatorMapWireDesc *)&stuff[1]; -- for (i=0,bit=1;iwhich&bit) { -- sli->maps[i].flags = from->flags; -- sli->maps[i].which_groups = from->whichGroups; -- sli->maps[i].groups = from->groups; -- sli->maps[i].which_mods = from->whichMods; -- sli->maps[i].mods.mask = from->mods; -- sli->maps[i].mods.real_mods = from->mods; -- sli->maps[i].mods.vmods= from->virtualMods; -- sli->maps[i].ctrls = from->ctrls; -- if (from->virtualMods!=0) { -- unsigned tmp; -- tmp= XkbMaskForVMask(xkbi->desc,from->virtualMods); -- sli->maps[i].mods.mask= from->mods|tmp; -- } -- from++; -- } -+ rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess); -+ if (rc == Success) -+ _XkbSetIndicatorMap(client, other, stuff->which, from); -+ } -+ } - } - -- XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); -- XkbApplyLedMapChanges(dev,sli,stuff->which,NULL,NULL,&cause); -- return client->noClientException; -+ return Success; - } - - /***====================================================================***/ -@@ -3039,96 +3289,205 @@ ProcXkbGetNamedIndicator(ClientPtr client) - return client->noClientException; - } - --/* FIXME: Needs to set indicator on all core-sending devices. */ --int --ProcXkbSetNamedIndicator(ClientPtr client) --{ -- DeviceIntPtr dev,kbd; -- XkbIndicatorMapPtr map; -- XkbSrvLedInfoPtr sli; -- register int led = 0; -- unsigned extDevReason; -- unsigned statec,namec,mapc; -- XkbEventCauseRec cause; -- xkbExtensionDeviceNotify ed; -- XkbChangesRec changes; -- -- REQUEST(xkbSetNamedIndicatorReq); -- REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); -- -- if (!(client->xkbClientFlags&_XkbClientInitialized)) -- return BadAccess; -- -- CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); -- CHK_ATOM_ONLY(stuff->indicator); -- CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); -- CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); -- -- extDevReason= 0; - -- sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID, -- XkbXI_IndicatorsMask); -- if (!sli) -- return BadAlloc; -+/** -+ * Find the IM on the device. -+ * Returns the map, or NULL if the map doesn't exist. -+ * If the return value is NULL, led_return is undefined. Otherwise, led_return -+ * is set to the led index of the map. -+ */ -+static XkbIndicatorMapPtr -+_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, -+ int *led_return) -+{ -+ XkbIndicatorMapPtr map; -+ int led; - -- statec= mapc= namec= 0; -- map= NULL; -+ /* search for the right indicator */ -+ map = NULL; - if (sli->names && sli->maps) { -- for (led=0;(lednames[led]==stuff->indicator) { -+ for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { -+ if (sli->names[led] == indicator) { - map= &sli->maps[led]; - break; - } - } - } -- if (map==NULL) { -- if (!stuff->createMap) -- return client->noClientException; -- for (led=0,map=NULL;(lednames)&&(sli->maps)&&(sli->names[led]==None)&& -- (!XkbIM_InUse(&sli->maps[led]))) { -- map= &sli->maps[led]; -- sli->names[led]= stuff->indicator; -- break; -- } -- } -- if (map==NULL) -- return client->noClientException; -- namec|= (1<namesPresent|= ((stuff->indicator!=None)?(1<names) && (sli->maps) && (sli->names[led] == None) && -+ (!XkbIM_InUse(&sli->maps[led]))) -+ { -+ map = &sli->maps[led]; -+ if (!dryRun) -+ sli->names[led] = indicator; -+ break; -+ } -+ } - } - -+ if (!map) -+ return BadAlloc; -+ -+ *led_return = led; -+ *map_return = map; -+ return Success; -+} -+ -+static int -+_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, -+ xkbSetNamedIndicatorReq *stuff) -+{ -+ unsigned int extDevReason; -+ unsigned int statec, namec, mapc; -+ XkbSrvLedInfoPtr sli; -+ int led = 0; -+ XkbIndicatorMapPtr map; -+ DeviceIntPtr kbd; -+ XkbEventCauseRec cause; -+ xkbExtensionDeviceNotify ed; -+ XkbChangesRec changes; -+ int rc; -+ -+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, -+ stuff->ledID, &map, &led, FALSE); -+ if (rc != Success || !map) /* oh-oh */ -+ return rc; -+ -+ namec = mapc = statec = 0; -+ extDevReason = 0; -+ -+ namec |= (1<namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); -+ extDevReason |= XkbXI_IndicatorNamesMask; -+ - if (stuff->setMap) { -- map->flags = stuff->flags; -- map->which_groups = stuff->whichGroups; -- map->groups = stuff->groups; -- map->which_mods = stuff->whichMods; -- map->mods.mask = stuff->realMods; -- map->mods.real_mods = stuff->realMods; -- map->mods.vmods= stuff->virtualMods; -- map->ctrls = stuff->ctrls; -- mapc|= (1<setState)&&((map->flags&XkbIM_NoExplicit)==0)) { -- if (stuff->on) sli->explicitState|= (1<explicitState&= ~(1<effectiveState^sli->explicitState)&(1<flags = stuff->flags; -+ map->which_groups = stuff->whichGroups; -+ map->groups = stuff->groups; -+ map->which_mods = stuff->whichMods; -+ map->mods.mask = stuff->realMods; -+ map->mods.real_mods = stuff->realMods; -+ map->mods.vmods= stuff->virtualMods; -+ map->ctrls = stuff->ctrls; -+ mapc|= (1<setState) && ((map->flags & XkbIM_NoExplicit) == 0)) -+ { -+ if (stuff->on) sli->explicitState |= (1<explicitState &= ~(1<effectiveState ^ sli->explicitState) & (1 << led)); - } -+ - bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); - bzero((char *)&changes,sizeof(XkbChangesRec)); - XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client); - if (namec) -- XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); -+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); - if (mapc) -- XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); -+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); - if (statec) -- XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); -+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); - -- kbd= dev; -+ kbd = dev; - if ((sli->flags&XkbSLI_HasOwnState)==0) -- kbd = inputInfo.keyboard; -- XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); -+ kbd = inputInfo.keyboard; -+ XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); -+ -+ return Success; -+} -+ -+int -+ProcXkbSetNamedIndicator(ClientPtr client) -+{ -+ int rc; -+ DeviceIntPtr dev; -+ int led = 0; -+ XkbIndicatorMapPtr map; -+ -+ REQUEST(xkbSetNamedIndicatorReq); -+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); -+ -+ if (!(client->xkbClientFlags&_XkbClientInitialized)) -+ return BadAccess; -+ -+ CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); -+ CHK_ATOM_ONLY(stuff->indicator); -+ CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); -+ CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); -+ -+ /* Dry-run for checks */ -+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator, -+ stuff->ledClass, stuff->ledID, -+ &map, &led, TRUE); -+ if (rc != Success || !map) /* couldn't be created or didn't exist */ -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd || -+ stuff->deviceSpec == XkbUseCorePtr) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->coreEvents && -+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) -+ { -+ rc = _XkbCreateIndicatorMap(other, stuff->indicator, -+ stuff->ledClass, stuff->ledID, -+ &map, &led, TRUE); -+ if (rc != Success || !map) -+ return rc; -+ } -+ } -+ } -+ -+ /* All checks passed, let's do it */ -+ rc = _XkbSetNamedIndicator(client, dev, stuff); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd || -+ stuff->deviceSpec == XkbUseCorePtr) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->coreEvents && -+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) -+ { -+ _XkbSetNamedIndicator(client, other, stuff); -+ } -+ } -+ } -+ - return client->noClientException; - } - -@@ -3528,17 +3887,323 @@ char * str; - return True; - } - --/* FIXME: Needs to set names on all core-sending devices. */ --int --ProcXkbSetNames(ClientPtr client) -+/** -+ * Check the device-dependent data in the request against the device. Returns -+ * Success, or the appropriate error code. -+ */ -+static int -+_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, -+ xkbSetNamesReq *stuff, CARD32 *data) - { -- DeviceIntPtr dev; - XkbDescRec *xkb; - XkbNamesRec *names; -- xkbNamesNotify nn; - CARD32 *tmp; - Atom bad; - -+ tmp = data; -+ xkb = dev->key->xkbInfo->desc; -+ names = xkb->names; -+ -+ -+ if (stuff->which & XkbKeyTypeNamesMask) { -+ int i; -+ CARD32 *old; -+ if ( stuff->nTypes<1 ) { -+ client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); -+ return BadValue; -+ } -+ if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { -+ client->errorValue = _XkbErrCode4(0x03,stuff->firstType, -+ stuff->nTypes, -+ xkb->map->num_types); -+ return BadValue; -+ } -+ if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { -+ client->errorValue = _XkbErrCode2(0x04,stuff->firstType); -+ return BadAccess; -+ } -+ old= tmp; -+ tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue= bad; -+ return BadAtom; -+ } -+ for (i=0;inTypes;i++,old++) { -+ if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) -+ client->errorValue= _XkbErrCode2(0x05,i); -+ } -+ } -+ if (stuff->which&XkbKTLevelNamesMask) { -+ unsigned i; -+ XkbKeyTypePtr type; -+ CARD8 * width; -+ if ( stuff->nKTLevels<1 ) { -+ client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); -+ return BadValue; -+ } -+ if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= -+ xkb->map->num_types) { -+ client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, -+ stuff->nKTLevels,xkb->map->num_types); -+ return BadValue; -+ } -+ width = (CARD8 *)tmp; -+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); -+ type = &xkb->map->types[stuff->firstKTLevel]; -+ for (i=0;inKTLevels;i++,type++) { -+ if (width[i]==0) -+ continue; -+ else if (width[i]!=type->num_levels) { -+ client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, -+ type->num_levels,width[i]); -+ return BadMatch; -+ } -+ tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue= bad; -+ return BadAtom; -+ } -+ } -+ } -+ if (stuff->which&XkbIndicatorNamesMask) { -+ if (stuff->indicators==0) { -+ client->errorValue= 0x08; -+ return BadMatch; -+ } -+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, -+ client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue= bad; -+ return BadAtom; -+ } -+ } -+ if (stuff->which&XkbVirtualModNamesMask) { -+ if (stuff->virtualMods==0) { -+ client->errorValue= 0x09; -+ return BadMatch; -+ } -+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, -+ (CARD32)stuff->virtualMods, -+ client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue = bad; -+ return BadAtom; -+ } -+ } -+ if (stuff->which&XkbGroupNamesMask) { -+ if (stuff->groupNames==0) { -+ client->errorValue= 0x0a; -+ return BadMatch; -+ } -+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, -+ (CARD32)stuff->groupNames, -+ client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue = bad; -+ return BadAtom; -+ } -+ } -+ if (stuff->which&XkbKeyNamesMask) { -+ if (stuff->firstKey<(unsigned)xkb->min_key_code) { -+ client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, -+ stuff->firstKey); -+ return BadValue; -+ } -+ if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| -+ (stuff->nKeys<1)) { -+ client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, -+ stuff->firstKey,stuff->nKeys); -+ return BadValue; -+ } -+ tmp+= stuff->nKeys; -+ } -+ if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { -+ tmp+= stuff->nKeyAliases*2; -+ } -+ if (stuff->which&XkbRGNamesMask) { -+ if ( stuff->nRadioGroups<1 ) { -+ client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); -+ return BadValue; -+ } -+ tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); -+ if (!tmp) { -+ client->errorValue= bad; -+ return BadAtom; -+ } -+ } -+ if ((tmp-((CARD32 *)stuff))!=stuff->length) { -+ client->errorValue = stuff->length; -+ return BadLength; -+ } -+ -+ -+ -+ return Success; -+} -+ -+static int -+_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) -+{ -+ XkbDescRec *xkb; -+ XkbNamesRec *names; -+ CARD32 *tmp; -+ xkbNamesNotify nn; -+ -+ tmp = (CARD32 *)&stuff[1]; -+ xkb = dev->key->xkbInfo->desc; -+ names = xkb->names; -+ -+ if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, -+ stuff->nKeyAliases)!=Success) { -+ return BadAlloc; -+ } -+ -+ bzero(&nn,sizeof(xkbNamesNotify)); -+ nn.changed= stuff->which; -+ tmp = (CARD32 *)&stuff[1]; -+ if (stuff->which&XkbKeycodesNameMask) -+ names->keycodes= *tmp++; -+ if (stuff->which&XkbGeometryNameMask) -+ names->geometry= *tmp++; -+ if (stuff->which&XkbSymbolsNameMask) -+ names->symbols= *tmp++; -+ if (stuff->which&XkbPhysSymbolsNameMask) -+ names->phys_symbols= *tmp++; -+ if (stuff->which&XkbTypesNameMask) -+ names->types= *tmp++; -+ if (stuff->which&XkbCompatNameMask) -+ names->compat= *tmp++; -+ if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { -+ register unsigned i; -+ register XkbKeyTypePtr type; -+ -+ type= &xkb->map->types[stuff->firstType]; -+ for (i=0;inTypes;i++,type++) { -+ type->name= *tmp++; -+ } -+ nn.firstType= stuff->firstType; -+ nn.nTypes= stuff->nTypes; -+ } -+ if (stuff->which&XkbKTLevelNamesMask) { -+ register XkbKeyTypePtr type; -+ register unsigned i; -+ CARD8 *width; -+ -+ width = (CARD8 *)tmp; -+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); -+ type= &xkb->map->types[stuff->firstKTLevel]; -+ for (i=0;inKTLevels;i++,type++) { -+ if (width[i]>0) { -+ if (type->level_names) { -+ register unsigned n; -+ for (n=0;nlevel_names[n]= tmp[n]; -+ } -+ } -+ tmp+= width[i]; -+ } -+ } -+ nn.firstLevelName= 0; -+ nn.nLevelNames= stuff->nTypes; -+ } -+ if (stuff->which&XkbIndicatorNamesMask) { -+ tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, -+ stuff->indicators); -+ nn.changedIndicators= stuff->indicators; -+ } -+ if (stuff->which&XkbVirtualModNamesMask) { -+ tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, -+ stuff->virtualMods); -+ nn.changedVirtualMods= stuff->virtualMods; -+ } -+ if (stuff->which&XkbGroupNamesMask) { -+ tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, -+ stuff->groupNames); -+ nn.changedVirtualMods= stuff->groupNames; -+ } -+ if (stuff->which&XkbKeyNamesMask) { -+ memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, -+ stuff->nKeys*XkbKeyNameLength); -+ tmp+= stuff->nKeys; -+ nn.firstKey= stuff->firstKey; -+ nn.nKeys= stuff->nKeys; -+ } -+ if (stuff->which&XkbKeyAliasesMask) { -+ if (stuff->nKeyAliases>0) { -+ register int na= stuff->nKeyAliases; -+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) -+ return BadAlloc; -+ memcpy((char *)names->key_aliases,(char *)tmp, -+ stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); -+ tmp+= stuff->nKeyAliases*2; -+ } -+ else if (names->key_aliases!=NULL) { -+ _XkbFree(names->key_aliases); -+ names->key_aliases= NULL; -+ names->num_key_aliases= 0; -+ } -+ nn.nAliases= names->num_key_aliases; -+ } -+ if (stuff->which&XkbRGNamesMask) { -+ if (stuff->nRadioGroups>0) { -+ register unsigned i,nrg; -+ nrg= stuff->nRadioGroups; -+ if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) -+ return BadAlloc; -+ -+ for (i=0;inRadioGroups;i++) { -+ names->radio_groups[i]= tmp[i]; -+ } -+ tmp+= stuff->nRadioGroups; -+ } -+ else if (names->radio_groups) { -+ _XkbFree(names->radio_groups); -+ names->radio_groups= NULL; -+ names->num_rg= 0; -+ } -+ nn.nRadioGroups= names->num_rg; -+ } -+ if (nn.changed) { -+ Bool needExtEvent; -+ needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; -+ XkbSendNamesNotify(dev,&nn); -+ if (needExtEvent) { -+ XkbSrvLedInfoPtr sli; -+ xkbExtensionDeviceNotify edev; -+ register int i; -+ register unsigned bit; -+ -+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, -+ XkbXI_IndicatorsMask); -+ sli->namesPresent= 0; -+ for (i=0,bit=1;iindicators[i]!=None) -+ sli->namesPresent|= bit; -+ } -+ bzero(&edev,sizeof(xkbExtensionDeviceNotify)); -+ edev.reason= XkbXI_IndicatorNamesMask; -+ edev.ledClass= KbdFeedbackClass; -+ edev.ledID= dev->kbdfeed->ctrl.id; -+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent; -+ edev.ledState= sli->effectiveState; -+ edev.firstBtn= 0; -+ edev.nBtns= 0; -+ edev.supported= XkbXI_AllFeaturesMask; -+ edev.unsupported= 0; -+ XkbSendExtensionDeviceNotify(dev,client,&edev); -+ } -+ } -+ return Success; -+} -+ -+int -+ProcXkbSetNames(ClientPtr client) -+{ -+ DeviceIntPtr dev; -+ CARD32 *tmp; -+ Atom bad; -+ int rc; -+ - REQUEST(xkbSetNamesReq); - REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); - -@@ -3548,8 +4213,7 @@ ProcXkbSetNames(ClientPtr client) - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); - -- xkb = dev->key->xkbInfo->desc; -- names = xkb->names; -+ /* check device-independent stuff */ - tmp = (CARD32 *)&stuff[1]; - - if (stuff->which&XkbKeycodesNameMask) { -@@ -3594,277 +4258,54 @@ ProcXkbSetNames(ClientPtr client) - return BadAtom; - } - } -- if (stuff->which&XkbKeyTypeNamesMask) { -- register int i; -- CARD32 *old; -- if ( stuff->nTypes<1 ) { -- client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); -- return BadValue; -- } -- if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { -- client->errorValue = _XkbErrCode4(0x03,stuff->firstType, -- stuff->nTypes, -- xkb->map->num_types); -- return BadValue; -- } -- if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { -- client->errorValue = _XkbErrCode2(0x04,stuff->firstType); -- return BadAccess; -- } -- old= tmp; -- tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); -- if (!tmp) { -- client->errorValue= bad; -- return BadAtom; -- } -- for (i=0;inTypes;i++,old++) { -- if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) -- client->errorValue= _XkbErrCode2(0x05,i); -- } -- } -- if (stuff->which&XkbKTLevelNamesMask) { -- register unsigned i; -- XkbKeyTypePtr type; -- CARD8 * width; -- if ( stuff->nKTLevels<1 ) { -- client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); -- return BadValue; -- } -- if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= -- xkb->map->num_types) { -- client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, -- stuff->nKTLevels,xkb->map->num_types); -- return BadValue; -- } -- width = (CARD8 *)tmp; -- tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); -- type = &xkb->map->types[stuff->firstKTLevel]; -- for (i=0;inKTLevels;i++,type++) { -- if (width[i]==0) -- continue; -- else if (width[i]!=type->num_levels) { -- client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, -- type->num_levels,width[i]); -- return BadMatch; -- } -- tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); -- if (!tmp) { -- client->errorValue= bad; -- return BadAtom; -- } -- } -- } -- if (stuff->which&XkbIndicatorNamesMask) { -- if (stuff->indicators==0) { -- client->errorValue= 0x08; -- return BadMatch; -- } -- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, -- client->swapped,&bad); -- if (!tmp) { -- client->errorValue= bad; -- return BadAtom; -- } -- } -- if (stuff->which&XkbVirtualModNamesMask) { -- if (stuff->virtualMods==0) { -- client->errorValue= 0x09; -- return BadMatch; -- } -- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, -- (CARD32)stuff->virtualMods, -- client->swapped,&bad); -- if (!tmp) { -- client->errorValue = bad; -- return BadAtom; -- } -- } -- if (stuff->which&XkbGroupNamesMask) { -- if (stuff->groupNames==0) { -- client->errorValue= 0x0a; -- return BadMatch; -- } -- tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, -- (CARD32)stuff->groupNames, -- client->swapped,&bad); -- if (!tmp) { -- client->errorValue = bad; -- return BadAtom; -- } -- } -- if (stuff->which&XkbKeyNamesMask) { -- if (stuff->firstKey<(unsigned)xkb->min_key_code) { -- client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, -- stuff->firstKey); -- return BadValue; -- } -- if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| -- (stuff->nKeys<1)) { -- client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, -- stuff->firstKey,stuff->nKeys); -- return BadValue; -- } -- tmp+= stuff->nKeys; -- } -- if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { -- tmp+= stuff->nKeyAliases*2; -- } -- if (stuff->which&XkbRGNamesMask) { -- if ( stuff->nRadioGroups<1 ) { -- client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); -- return BadValue; -- } -- tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); -- if (!tmp) { -- client->errorValue= bad; -- return BadAtom; -- } -- } -- if ((tmp-((CARD32 *)stuff))!=stuff->length) { -- client->errorValue = stuff->length; -- return BadLength; -- } -- if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, -- stuff->nKeyAliases)!=Success) { -- return BadAlloc; -+ -+ /* start of device-dependent tests */ -+ rc = _XkbSetNamesCheck(client, dev, stuff, tmp); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ rc = _XkbSetNamesCheck(client, other, stuff, tmp); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } - } - - /* everything is okay -- update names */ -- bzero(&nn,sizeof(xkbNamesNotify)); -- nn.changed= stuff->which; -- tmp = (CARD32 *)&stuff[1]; -- if (stuff->which&XkbKeycodesNameMask) -- names->keycodes= *tmp++; -- if (stuff->which&XkbGeometryNameMask) -- names->geometry= *tmp++; -- if (stuff->which&XkbSymbolsNameMask) -- names->symbols= *tmp++; -- if (stuff->which&XkbPhysSymbolsNameMask) -- names->phys_symbols= *tmp++; -- if (stuff->which&XkbTypesNameMask) -- names->types= *tmp++; -- if (stuff->which&XkbCompatNameMask) -- names->compat= *tmp++; -- if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { -- register unsigned i; -- register XkbKeyTypePtr type; - -- type= &xkb->map->types[stuff->firstType]; -- for (i=0;inTypes;i++,type++) { -- type->name= *tmp++; -- } -- nn.firstType= stuff->firstType; -- nn.nTypes= stuff->nTypes; -- } -- if (stuff->which&XkbKTLevelNamesMask) { -- register XkbKeyTypePtr type; -- register unsigned i; -- CARD8 *width; -- -- width = (CARD8 *)tmp; -- tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); -- type= &xkb->map->types[stuff->firstKTLevel]; -- for (i=0;inKTLevels;i++,type++) { -- if (width[i]>0) { -- if (type->level_names) { -- register unsigned n; -- for (n=0;nlevel_names[n]= tmp[n]; -- } -- } -- tmp+= width[i]; -- } -- } -- nn.firstLevelName= 0; -- nn.nLevelNames= stuff->nTypes; -- } -- if (stuff->which&XkbIndicatorNamesMask) { -- tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, -- stuff->indicators); -- nn.changedIndicators= stuff->indicators; -- } -- if (stuff->which&XkbVirtualModNamesMask) { -- tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, -- stuff->virtualMods); -- nn.changedVirtualMods= stuff->virtualMods; -- } -- if (stuff->which&XkbGroupNamesMask) { -- tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, -- stuff->groupNames); -- nn.changedVirtualMods= stuff->groupNames; -- } -- if (stuff->which&XkbKeyNamesMask) { -- memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, -- stuff->nKeys*XkbKeyNameLength); -- tmp+= stuff->nKeys; -- nn.firstKey= stuff->firstKey; -- nn.nKeys= stuff->nKeys; -- } -- if (stuff->which&XkbKeyAliasesMask) { -- if (stuff->nKeyAliases>0) { -- register int na= stuff->nKeyAliases; -- if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) -- return BadAlloc; -- memcpy((char *)names->key_aliases,(char *)tmp, -- stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); -- tmp+= stuff->nKeyAliases*2; -- } -- else if (names->key_aliases!=NULL) { -- _XkbFree(names->key_aliases); -- names->key_aliases= NULL; -- names->num_key_aliases= 0; -- } -- nn.nAliases= names->num_key_aliases; -- } -- if (stuff->which&XkbRGNamesMask) { -- if (stuff->nRadioGroups>0) { -- register unsigned i,nrg; -- nrg= stuff->nRadioGroups; -- if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) -- return BadAlloc; -+ rc = _XkbSetNames(client, dev, stuff); -+ if (rc != Success) -+ return rc; - -- for (i=0;inRadioGroups;i++) { -- names->radio_groups[i]= tmp[i]; -- } -- tmp+= stuff->nRadioGroups; -- } -- else if (names->radio_groups) { -- _XkbFree(names->radio_groups); -- names->radio_groups= NULL; -- names->num_rg= 0; -- } -- nn.nRadioGroups= names->num_rg; -- } -- if (nn.changed) { -- Bool needExtEvent; -- needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; -- XkbSendNamesNotify(dev,&nn); -- if (needExtEvent) { -- XkbSrvLedInfoPtr sli; -- xkbExtensionDeviceNotify edev; -- register int i; -- register unsigned bit; -- -- sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, -- XkbXI_IndicatorsMask); -- sli->namesPresent= 0; -- for (i=0,bit=1;iindicators[i]!=None) -- sli->namesPresent|= bit; -- } -- bzero(&edev,sizeof(xkbExtensionDeviceNotify)); -- edev.reason= XkbXI_IndicatorNamesMask; -- edev.ledClass= KbdFeedbackClass; -- edev.ledID= dev->kbdfeed->ctrl.id; -- edev.ledsDefined= sli->namesPresent|sli->mapsPresent; -- edev.ledState= sli->effectiveState; -- edev.firstBtn= 0; -- edev.nBtns= 0; -- edev.supported= XkbXI_AllFeaturesMask; -- edev.unsupported= 0; -- XkbSendExtensionDeviceNotify(dev,client,&edev); -- } -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ _XkbSetNames(client, other, stuff); -+ } -+ } - } -+ -+ /* everything is okay -- update names */ -+ - return client->noClientException; - } - -@@ -4826,60 +5267,49 @@ char * wire; - return Success; - } - --/* FIXME: Needs to set geom on all core-sending devices. */ --int --ProcXkbSetGeometry(ClientPtr client) -+static int -+_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) - { -- DeviceIntPtr dev; -- XkbGeometryPtr geom,old; -- XkbGeometrySizesRec sizes; -- Status status; - XkbDescPtr xkb; - Bool new_name; - xkbNewKeyboardNotify nkn; -- -- REQUEST(xkbSetGeometryReq); -- REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); -- -- if (!(client->xkbClientFlags&_XkbClientInitialized)) -- return BadAccess; -- -- CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -- CHK_ATOM_OR_NONE(stuff->name); -+ XkbGeometryPtr geom,old; -+ XkbGeometrySizesRec sizes; -+ Status status; - - xkb= dev->key->xkbInfo->desc; - old= xkb->geom; - xkb->geom= NULL; - -- sizes.which= XkbGeomAllMask; -+ sizes.which= XkbGeomAllMask; - sizes.num_properties= stuff->nProperties; -- sizes.num_colors= stuff->nColors; -- sizes.num_shapes= stuff->nShapes; -- sizes.num_sections= stuff->nSections; -- sizes.num_doodads= stuff->nDoodads; -+ sizes.num_colors= stuff->nColors; -+ sizes.num_shapes= stuff->nShapes; -+ sizes.num_sections= stuff->nSections; -+ sizes.num_doodads= stuff->nDoodads; - sizes.num_key_aliases= stuff->nKeyAliases; - if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { -- xkb->geom= old; -- return status; -+ xkb->geom= old; -+ return status; - } - geom= xkb->geom; - geom->name= stuff->name; - geom->width_mm= stuff->widthMM; - geom->height_mm= stuff->heightMM; - if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { -- XkbFreeGeometry(geom,XkbGeomAllMask,True); -- xkb->geom= old; -- return status; -+ XkbFreeGeometry(geom,XkbGeomAllMask,True); -+ xkb->geom= old; -+ return status; - } - new_name= (xkb->names->geometry!=geom->name); - xkb->names->geometry= geom->name; - if (old) -- XkbFreeGeometry(old,XkbGeomAllMask,True); -+ XkbFreeGeometry(old,XkbGeomAllMask,True); - if (new_name) { -- xkbNamesNotify nn; -- bzero(&nn,sizeof(xkbNamesNotify)); -- nn.changed= XkbGeometryNameMask; -- XkbSendNamesNotify(dev,&nn); -+ xkbNamesNotify nn; -+ bzero(&nn,sizeof(xkbNamesNotify)); -+ nn.changed= XkbGeometryNameMask; -+ XkbSendNamesNotify(dev,&nn); - } - nkn.deviceID= nkn.oldDeviceID= dev->id; - nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; -@@ -4891,6 +5321,43 @@ ProcXkbSetGeometry(ClientPtr client) - return Success; - } - -+int -+ProcXkbSetGeometry(ClientPtr client) -+{ -+ DeviceIntPtr dev; -+ Status status; -+ int rc; -+ -+ REQUEST(xkbSetGeometryReq); -+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); -+ -+ if (!(client->xkbClientFlags&_XkbClientInitialized)) -+ return BadAccess; -+ -+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -+ CHK_ATOM_OR_NONE(stuff->name); -+ -+ rc = _XkbSetGeometry(client, dev, stuff); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if ((other != dev) && other->key && other->coreEvents) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ _XkbSetGeometry(client, other, stuff); -+ } -+ } -+ } -+ -+ return Success; -+} -+ - /***====================================================================***/ - - int -@@ -5972,25 +6439,15 @@ DeviceIntPtr kbd; - return (char *)ledWire; - } - --/* FIXME: Needs to set info on all core-sending devices. */ --int --ProcXkbSetDeviceInfo(ClientPtr client) --{ --DeviceIntPtr dev; --unsigned change; --char * wire; --xkbExtensionDeviceNotify ed; - -- REQUEST(xkbSetDeviceInfoReq); -- REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); -- -- if (!(client->xkbClientFlags&_XkbClientInitialized)) -- return BadAccess; -+static int -+_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, -+ xkbSetDeviceInfoReq *stuff) -+{ -+ unsigned change; -+ char *wire; - -- change= stuff->change; -- -- CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -- CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask); -+ change = stuff->change; - - wire= (char *)&stuff[1]; - if (change&XkbXI_ButtonActionsMask) { -@@ -6015,6 +6472,17 @@ xkbExtensionDeviceNotify ed; - if (((wire-((char *)stuff))/4)!=stuff->length) - return BadLength; - -+ return Success; -+} -+ -+static int -+_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, -+ xkbSetDeviceInfoReq *stuff) -+{ -+ unsigned change; -+ char *wire; -+ xkbExtensionDeviceNotify ed; -+ - bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); - ed.deviceID= dev->id; - wire= (char *)&stuff[1]; -@@ -6055,6 +6523,78 @@ xkbExtensionDeviceNotify ed; - } - if ((stuff->change)&&(ed.reason)) - XkbSendExtensionDeviceNotify(dev,client,&ed); -+ return Success; -+} -+ -+int -+ProcXkbSetDeviceInfo(ClientPtr client) -+{ -+ unsigned int change; -+ DeviceIntPtr dev; -+ int loop = 0; -+ int rc; -+ -+ REQUEST(xkbSetDeviceInfoReq); -+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); -+ -+ if (!(client->xkbClientFlags&_XkbClientInitialized)) -+ return BadAccess; -+ -+ change = stuff->change; -+ -+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); -+ CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask); -+ -+ rc = _XkbSetDeviceInfoCheck(client, dev, stuff); -+ -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if (((other != dev) && other->coreEvents) && -+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || -+ (stuff->deviceSpec == XkbUseCorePtr && other->button))) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ rc = _XkbSetDeviceInfoCheck(client, other, stuff); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } -+ } -+ -+ /* checks done, apply */ -+ rc = _XkbSetDeviceInfo(client, dev, stuff); -+ if (rc != Success) -+ return rc; -+ -+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) -+ { -+ DeviceIntPtr other; -+ for (other = inputInfo.devices; other; other = other->next) -+ { -+ if (((other != dev) && other->coreEvents) && -+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || -+ (stuff->deviceSpec == XkbUseCorePtr && other->button))) -+ { -+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); -+ if (rc == Success) -+ { -+ rc = _XkbSetDeviceInfo(client, other, stuff); -+ if (rc != Success) -+ return rc; -+ } -+ } -+ } -+ } -+ - return client->noClientException; - } - --- -1.5.5.1 -