summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:54 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:54 +0000
commitded6147bfb5d75ff1e67c858040a628b61bc17d1 (patch)
tree82355105e93cdac89ef7d987424351c77545faf0
parentcb6ef07bf01e72d1a6e6e83ceb7f76d6534da941 (diff)
R6.6 is the Xorg base-lineXORG-MAIN
-rw-r--r--Xext/EVI.c179
-rw-r--r--Xext/EVIstruct.h53
-rw-r--r--Xext/README.xtest1-ddx90
-rw-r--r--Xext/SecurityPolicy88
-rw-r--r--Xext/appgroup.c810
-rw-r--r--Xext/bigreq.c86
-rw-r--r--Xext/cup.c340
-rw-r--r--Xext/dpms.c433
-rw-r--r--Xext/dpmsstubs.c48
-rw-r--r--Xext/mbuf.c2041
-rw-r--r--Xext/mbufbf.c1052
-rw-r--r--Xext/mbufpx.c646
-rw-r--r--Xext/mitmisc.c153
-rw-r--r--Xext/panoramiX.c780
-rw-r--r--Xext/panoramiXSwap.c158
-rw-r--r--Xext/panoramiXprocs.c3034
-rw-r--r--Xext/sampleEVI.c97
-rw-r--r--Xext/security.c1995
-rw-r--r--Xext/shape.c1217
-rw-r--r--Xext/shm.c1010
-rw-r--r--Xext/sleepuntil.c211
-rw-r--r--Xext/sync.c2322
-rw-r--r--Xext/xcmisc.c218
-rw-r--r--Xext/xprint.c2873
-rw-r--r--Xext/xtest.c533
-rw-r--r--Xext/xtest1dd.c1613
-rw-r--r--Xext/xtest1di.c966
-rw-r--r--Xi/allowev.c139
-rw-r--r--Xi/chgdctl.c209
-rw-r--r--Xi/chgfctl.c649
-rw-r--r--Xi/chgkbd.c208
-rw-r--r--Xi/chgkmap.c129
-rw-r--r--Xi/chgprop.c165
-rw-r--r--Xi/chgptr.c252
-rw-r--r--Xi/closedev.c185
-rw-r--r--Xi/devbell.c167
-rw-r--r--Xi/exevents.c1388
-rw-r--r--Xi/extinit.c962
-rw-r--r--Xi/getbmap.c147
-rw-r--r--Xi/getdctl.c224
-rw-r--r--Xi/getfctl.c421
-rw-r--r--Xi/getfocus.c151
-rw-r--r--Xi/getkmap.c171
-rw-r--r--Xi/getmmap.c151
-rw-r--r--Xi/getprop.c207
-rw-r--r--Xi/getselev.c189
-rw-r--r--Xi/getvers.c148
-rw-r--r--Xi/grabdev.c225
-rw-r--r--Xi/grabdevb.c163
-rw-r--r--Xi/grabdevk.c169
-rw-r--r--Xi/gtmotion.c206
-rw-r--r--Xi/listdev.c409
-rw-r--r--Xi/opendev.c199
-rw-r--r--Xi/queryst.c208
-rw-r--r--Xi/selectev.c150
-rw-r--r--Xi/sendexev.c173
-rw-r--r--Xi/setbmap.c163
-rw-r--r--Xi/setdval.c167
-rw-r--r--Xi/setfocus.c119
-rw-r--r--Xi/setmmap.c157
-rw-r--r--Xi/setmode.c151
-rw-r--r--Xi/stubs.c307
-rw-r--r--Xi/ungrdev.c118
-rw-r--r--Xi/ungrdevb.c172
-rw-r--r--Xi/ungrdevk.c178
-rw-r--r--XpConfig/C/print/Xprinters43
-rw-r--r--XpConfig/C/print/attributes/document38
-rw-r--r--XpConfig/C/print/attributes/job25
-rw-r--r--XpConfig/C/print/attributes/printer80
-rw-r--r--XpConfig/C/print/ddx-config/raster/pcl39
-rw-r--r--XpConfig/C/print/ddx-config/raster/postscript0
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00051.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00052.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00053.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00054.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00055.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00056.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00057.pmfbin0 -> 5632 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00058.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00059.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00060.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00061.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00062.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00063.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00064.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00065.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00066.pmfbin0 -> 5732 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00067.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00068.pmfbin0 -> 5732 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00069.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00070.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00071.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00072.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00073.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00074.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00075.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00076.pmfbin0 -> 5716 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00077.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00079.pmfbin0 -> 5656 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00080.pmfbin0 -> 5664 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00081.pmfbin0 -> 5672 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00082.pmfbin0 -> 5660 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00083.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00084.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00085.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00086.pmfbin0 -> 5716 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00087.pmfbin0 -> 5752 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00088.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00089.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00090.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00091.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00092.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00093.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/9nb00094.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/README197
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/fonts.alias0
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/fonts.dir45
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/fonts/lpr0ye1a.pmfbin0 -> 4296 bytes
-rw-r--r--XpConfig/C/print/models/HPDJ1600C/model-config44
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00051.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00052.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00053.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00054.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00055.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00056.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00057.pmfbin0 -> 5632 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00058.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00059.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00060.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00061.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00062.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00063.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00064.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00065.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00066.pmfbin0 -> 5732 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00067.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00068.pmfbin0 -> 5732 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00069.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00070.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00071.pmfbin0 -> 5740 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00072.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00073.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00074.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00075.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00076.pmfbin0 -> 5716 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00077.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00079.pmfbin0 -> 5656 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00080.pmfbin0 -> 5664 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00081.pmfbin0 -> 5672 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00082.pmfbin0 -> 5660 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00083.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00084.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00085.pmfbin0 -> 5724 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00086.pmfbin0 -> 5716 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00087.pmfbin0 -> 5752 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00088.pmfbin0 -> 5720 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00089.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00090.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00091.pmfbin0 -> 5744 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00092.pmfbin0 -> 5736 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00093.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/9nb00094.pmfbin0 -> 5728 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/README203
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/fonts.alias0
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/fonts.dir45
-rw-r--r--XpConfig/C/print/models/HPLJ4family/fonts/lpr0ye1a.pmfbin0 -> 4296 bytes
-rw-r--r--XpConfig/C/print/models/HPLJ4family/model-config44
-rw-r--r--XpConfig/C/print/models/SPSPARC2/model-config13
-rw-r--r--Xprint/AttrValid.c702
-rw-r--r--Xprint/AttrValid.h208
-rw-r--r--Xprint/DiPrint.h54
-rw-r--r--Xprint/Init.c1805
-rw-r--r--Xprint/Oid.c3177
-rw-r--r--Xprint/Oid.h289
-rw-r--r--Xprint/OidDefs.h163
-rw-r--r--Xprint/OidStrs.h165
-rw-r--r--Xprint/Util.c360
-rw-r--r--Xprint/ValTree.c187
-rw-r--r--Xprint/attributes.c1575
-rw-r--r--Xprint/attributes.h78
-rw-r--r--Xprint/ddxInit.c364
-rw-r--r--Xprint/mediaSizes.c777
-rw-r--r--Xprint/pcl/Pcl.h580
-rw-r--r--Xprint/pcl/PclArc.c264
-rw-r--r--Xprint/pcl/PclArea.c487
-rw-r--r--Xprint/pcl/PclAttVal.c203
-rw-r--r--Xprint/pcl/PclAttr.c83
-rw-r--r--Xprint/pcl/PclColor.c860
-rw-r--r--Xprint/pcl/PclCursor.c110
-rw-r--r--Xprint/pcl/PclDef.h64
-rw-r--r--Xprint/pcl/PclFonts.c69
-rw-r--r--Xprint/pcl/PclGC.c1064
-rw-r--r--Xprint/pcl/PclInit.c658
-rw-r--r--Xprint/pcl/PclLine.c314
-rw-r--r--Xprint/pcl/PclMisc.c293
-rw-r--r--Xprint/pcl/PclPixel.c154
-rw-r--r--Xprint/pcl/PclPixmap.c80
-rw-r--r--Xprint/pcl/PclPolygon.c354
-rw-r--r--Xprint/pcl/PclPrint.c718
-rw-r--r--Xprint/pcl/PclSFonts.c431
-rw-r--r--Xprint/pcl/PclSFonts.h112
-rw-r--r--Xprint/pcl/PclSpans.c136
-rw-r--r--Xprint/pcl/PclText.c937
-rw-r--r--Xprint/pcl/PclWindow.c450
-rw-r--r--Xprint/pcl/Pclmap.h195
-rw-r--r--Xprint/ps/Ps.h520
-rw-r--r--Xprint/ps/PsArc.c178
-rw-r--r--Xprint/ps/PsArea.c464
-rw-r--r--Xprint/ps/PsAttVal.c202
-rw-r--r--Xprint/ps/PsAttr.c113
-rw-r--r--Xprint/ps/PsCache.c324
-rw-r--r--Xprint/ps/PsColor.c223
-rw-r--r--Xprint/ps/PsDef.h93
-rw-r--r--Xprint/ps/PsFonts.c185
-rw-r--r--Xprint/ps/PsGC.c380
-rw-r--r--Xprint/ps/PsInit.c413
-rw-r--r--Xprint/ps/PsLine.c188
-rw-r--r--Xprint/ps/PsMisc.c320
-rw-r--r--Xprint/ps/PsPixel.c153
-rw-r--r--Xprint/ps/PsPixmap.c597
-rw-r--r--Xprint/ps/PsPolygon.c232
-rw-r--r--Xprint/ps/PsPrint.c434
-rw-r--r--Xprint/ps/PsSpans.c162
-rw-r--r--Xprint/ps/PsText.c478
-rw-r--r--Xprint/ps/PsWindow.c458
-rw-r--r--Xprint/ps/psout.c1623
-rw-r--r--Xprint/ps/psout.h202
-rw-r--r--Xprint/raster/Raster.c1585
-rw-r--r--Xprint/raster/Raster.h106
-rw-r--r--Xprint/raster/RasterAttVal.c265
-rw-r--r--cfb/cfb.h1494
-rw-r--r--cfb/cfb8bit.c466
-rw-r--r--cfb/cfb8bit.h1196
-rw-r--r--cfb/cfb8line.c915
-rw-r--r--cfb/cfballpriv.c84
-rw-r--r--cfb/cfbbitblt.c759
-rw-r--r--cfb/cfbblt.c633
-rw-r--r--cfb/cfbbres.c233
-rw-r--r--cfb/cfbbresd.c258
-rw-r--r--cfb/cfbbstore.c147
-rw-r--r--cfb/cfbcmap.c587
-rw-r--r--cfb/cfbfillarc.c265
-rw-r--r--cfb/cfbfillrct.c286
-rw-r--r--cfb/cfbfillsp.c960
-rw-r--r--cfb/cfbgc.c791
-rw-r--r--cfb/cfbgetsp.c164
-rw-r--r--cfb/cfbglblt8.c441
-rw-r--r--cfb/cfbhrzvert.c179
-rw-r--r--cfb/cfbigblt8.c97
-rw-r--r--cfb/cfbimage.c200
-rw-r--r--cfb/cfbline.c743
-rw-r--r--cfb/cfbmap.h187
-rw-r--r--cfb/cfbmskbits.c1210
-rw-r--r--cfb/cfbmskbits.h672
-rw-r--r--cfb/cfbpixmap.c370
-rw-r--r--cfb/cfbply1rct.c318
-rw-r--r--cfb/cfbpntwin.c370
-rw-r--r--cfb/cfbpolypnt.c150
-rw-r--r--cfb/cfbpush8.c184
-rw-r--r--cfb/cfbrctstp8.c588
-rw-r--r--cfb/cfbrrop.c221
-rw-r--r--cfb/cfbrrop.h150
-rw-r--r--cfb/cfbscrinit.c195
-rw-r--r--cfb/cfbsetsp.c280
-rw-r--r--cfb/cfbsolid.c296
-rw-r--r--cfb/cfbteblt8.c583
-rw-r--r--cfb/cfbtegblt.c201
-rw-r--r--cfb/cfbtile32.c352
-rw-r--r--cfb/cfbtileodd.c1080
-rw-r--r--cfb/cfbwindow.c334
-rw-r--r--cfb/cfbzerarc.c218
-rw-r--r--cfb/stip68kgnu.h128
-rw-r--r--cfb/stipmips.s281
-rw-r--r--cfb/stipsparc.s280
-rw-r--r--cfb/stipsprc32.s281
-rw-r--r--dbe/dbe.c1977
-rw-r--r--dbe/dbestruct.h261
-rw-r--r--dbe/midbe.c848
-rw-r--r--dbe/midbe.h48
-rw-r--r--dbe/midbestr.h96
-rw-r--r--dix/BuiltInAtoms329
-rw-r--r--dix/CHANGES17
-rw-r--r--dix/atom.c211
-rw-r--r--dix/buildatoms42
-rw-r--r--dix/colormap.c2869
-rw-r--r--dix/cursor.c399
-rw-r--r--dix/devices.c1687
-rw-r--r--dix/dispatch.c3966
-rw-r--r--dix/dixfonts.c2128
-rw-r--r--dix/dixutils.c969
-rw-r--r--dix/events.c3717
-rw-r--r--dix/extension.c470
-rw-r--r--dix/ffs.c37
-rw-r--r--dix/gc.c1330
-rw-r--r--dix/globals.c139
-rw-r--r--dix/glyphcurs.c197
-rw-r--r--dix/grabs.c441
-rw-r--r--dix/initatoms.c79
-rw-r--r--dix/main.c678
-rw-r--r--dix/pixmap.c147
-rw-r--r--dix/privates.c351
-rw-r--r--dix/property.c724
-rw-r--r--dix/resource.c855
-rw-r--r--dix/swaprep.c1443
-rw-r--r--dix/swapreq.c1173
-rw-r--r--dix/tables.c615
-rw-r--r--dix/window.c3698
-rw-r--r--dix/xpstubs.c54
-rw-r--r--doc/Xserver.man.pre679
-rw-r--r--hw/vfb/InitInput.c357
-rw-r--r--hw/vfb/InitOutput.c981
-rw-r--r--hw/vfb/Xvfb.man.pre128
-rw-r--r--hw/vfb/lk201kbd.h159
-rw-r--r--hw/xfree86/common/atKeynames.h335
-rw-r--r--hw/xfree86/common/compiler.h1460
-rw-r--r--hw/xfree86/common/scoasm.h112
-rw-r--r--hw/xfree86/common/xf86.h743
-rw-r--r--hw/xfree86/common/xf86Config.c3934
-rw-r--r--hw/xfree86/common/xf86Cursor.c326
-rw-r--r--hw/xfree86/common/xf86Events.c1575
-rw-r--r--hw/xfree86/common/xf86Init.c834
-rw-r--r--hw/xfree86/common/xf86Io.c542
-rw-r--r--hw/xfree86/common/xf86Kbd.c407
-rw-r--r--hw/xfree86/common/xf86KbdBSD.c687
-rw-r--r--hw/xfree86/common/xf86KbdLnx.c697
-rw-r--r--hw/xfree86/common/xf86KbdMach.c312
-rw-r--r--hw/xfree86/common/xf86Keymap.h449
-rw-r--r--hw/xfree86/common/xf86Priv.h175
-rw-r--r--hw/xfree86/common/xf86Version.h23
-rw-r--r--hw/xfree86/common/xf86XKB.c118
-rw-r--r--hw/xfree86/common/xf86Xinput.c1264
-rw-r--r--hw/xfree86/common/xf86Xinput.h280
-rw-r--r--hw/xfree86/dixmods/extmod/xf86vmode.c1429
-rw-r--r--hw/xfree86/os-support/README.OS-lib437
-rw-r--r--hw/xfree86/os-support/assyntax.h725
-rw-r--r--hw/xfree86/os-support/bsd/bsd_VTsw.c92
-rw-r--r--hw/xfree86/os-support/bsd/bsd_init.c780
-rw-r--r--hw/xfree86/os-support/bsd/bsd_io.c257
-rw-r--r--hw/xfree86/os-support/bsd/bsd_jstk.c180
-rw-r--r--hw/xfree86/os-support/linux/lnx_init.c274
-rw-r--r--hw/xfree86/os-support/linux/lnx_io.c136
-rw-r--r--hw/xfree86/os-support/linux/lnx_jstk.c173
-rw-r--r--hw/xfree86/os-support/linux/lnx_video.c634
-rw-r--r--hw/xfree86/os-support/lynxos/lynx_init.c198
-rw-r--r--hw/xfree86/os-support/lynxos/lynx_io.c172
-rw-r--r--hw/xfree86/os-support/lynxos/lynx_mmap.c66
-rw-r--r--hw/xfree86/os-support/lynxos/lynx_video.c167
-rw-r--r--hw/xfree86/os-support/misc/xf86_IlHack.c14
-rw-r--r--hw/xfree86/os-support/misc/xf86_Util.c126
-rw-r--r--hw/xfree86/os-support/sco/VTsw_sco.c94
-rw-r--r--hw/xfree86/os-support/sco/sco_init.c261
-rw-r--r--hw/xfree86/os-support/sco/sco_io.c117
-rw-r--r--hw/xfree86/os-support/sco/sco_mouse.c175
-rw-r--r--hw/xfree86/os-support/sco/sco_video.c284
-rw-r--r--hw/xfree86/os-support/shared/VTsw_noop.c51
-rw-r--r--hw/xfree86/os-support/shared/VTsw_usl.c80
-rw-r--r--hw/xfree86/os-support/shared/bios_devmem.c139
-rw-r--r--hw/xfree86/os-support/shared/ioperm_noop.c60
-rw-r--r--hw/xfree86/os-support/shared/posix_tty.c174
-rw-r--r--hw/xfree86/os-support/shared/std_kbdEv.c49
-rw-r--r--hw/xfree86/os-support/shared/sysv_kbd.c105
-rw-r--r--hw/xfree86/os-support/sysv/sysv_init.c257
-rw-r--r--hw/xfree86/os-support/sysv/sysv_io.c98
-rw-r--r--hw/xfree86/os-support/sysv/sysv_video.c589
-rw-r--r--hw/xfree86/os-support/sysv/xqueue.c406
-rw-r--r--hw/xfree86/os-support/xf86_OSlib.h533
-rw-r--r--hw/xfree86/os-support/xf86_OSproc.h394
-rw-r--r--hw/xfree86/utils/kbd_mode/bsd-kbd_mode.c96
-rw-r--r--hw/xfree86/utils/kbd_mode/bsd-kbd_mode.man.pre36
-rw-r--r--hw/xfree86/utils/kbd_mode/sun-kbd_mode.c150
-rw-r--r--hw/xfree86/utils/kbd_mode/sun-kbd_mode.man.pre50
-rw-r--r--hw/xfree86/utils/scanpci/scanpci.c1790
-rw-r--r--hw/xfree86/utils/xorgconfig/Cards2003
-rw-r--r--hw/xfree86/utils/xorgconfig/cards.c285
-rw-r--r--hw/xfree86/utils/xorgconfig/cards.h36
-rw-r--r--hw/xnest/Args.c188
-rw-r--r--hw/xnest/Args.h38
-rw-r--r--hw/xnest/Color.c501
-rw-r--r--hw/xnest/Color.h56
-rw-r--r--hw/xnest/Cursor.c214
-rw-r--r--hw/xnest/Display.c201
-rw-r--r--hw/xnest/Display.h46
-rw-r--r--hw/xnest/Drawable.h27
-rw-r--r--hw/xnest/Events.c189
-rw-r--r--hw/xnest/Events.h28
-rw-r--r--hw/xnest/Font.c87
-rw-r--r--hw/xnest/GC.c345
-rw-r--r--hw/xnest/GCOps.c387
-rw-r--r--hw/xnest/GCOps.h43
-rw-r--r--hw/xnest/GetTime.c43
-rw-r--r--hw/xnest/Handlers.c43
-rw-r--r--hw/xnest/Handlers.h22
-rw-r--r--hw/xnest/Init.c147
-rw-r--r--hw/xnest/Init.h21
-rw-r--r--hw/xnest/Keyboard.c165
-rw-r--r--hw/xnest/Keyboard.h26
-rw-r--r--hw/xnest/Pixmap.c130
-rw-r--r--hw/xnest/Pointer.c73
-rw-r--r--hw/xnest/Pointer.h28
-rw-r--r--hw/xnest/Screen.c376
-rw-r--r--hw/xnest/Screen.h26
-rw-r--r--hw/xnest/TestExt.c65
-rw-r--r--hw/xnest/Visual.c67
-rw-r--r--hw/xnest/Visual.h26
-rw-r--r--hw/xnest/Window.c555
-rw-r--r--hw/xnest/XNFont.h36
-rw-r--r--hw/xnest/XNGC.h43
-rw-r--r--hw/xnest/XNWindow.h79
-rw-r--r--hw/xnest/Xnest.h95
-rw-r--r--hw/xnest/Xnest.man.pre261
-rw-r--r--hw/xnest/icon14
-rw-r--r--hw/xnest/screensaver686
-rw-r--r--include/closestr.h138
-rw-r--r--include/closure.h57
-rw-r--r--include/colormap.h233
-rw-r--r--include/colormapst.h120
-rw-r--r--include/cursor.h151
-rw-r--r--include/cursorstr.h80
-rw-r--r--include/dix.h1090
-rw-r--r--include/dixfont.h331
-rw-r--r--include/dixfontstr.h95
-rw-r--r--include/dixstruct.h220
-rw-r--r--include/extension.h80
-rw-r--r--include/extnsionst.h174
-rw-r--r--include/gc.h231
-rw-r--r--include/gcstruct.h396
-rw-r--r--include/input.h496
-rw-r--r--include/inputstr.h316
-rw-r--r--include/misc.h271
-rw-r--r--include/miscstruct.h67
-rw-r--r--include/opaque.h56
-rw-r--r--include/os.h707
-rw-r--r--include/pixmap.h123
-rw-r--r--include/pixmapstr.h83
-rw-r--r--include/property.h78
-rw-r--r--include/propertyst.h74
-rw-r--r--include/region.h53
-rw-r--r--include/regionstr.h408
-rw-r--r--include/resource.h281
-rw-r--r--include/rgb.h54
-rw-r--r--include/screenint.h164
-rw-r--r--include/scrnintstr.h933
-rw-r--r--include/selection.h68
-rw-r--r--include/servermd.h483
-rw-r--r--include/site.h137
-rw-r--r--include/validate.h41
-rw-r--r--include/window.h350
-rw-r--r--include/windowstr.h227
-rw-r--r--lbx/lbxcmap.c1148
-rw-r--r--lbx/lbxdata.h44
-rw-r--r--lbx/lbxdix.c887
-rw-r--r--lbx/lbxexts.c270
-rw-r--r--lbx/lbxgfx.c867
-rw-r--r--lbx/lbxmain.c1819
-rw-r--r--lbx/lbxopts.c817
-rw-r--r--lbx/lbxprop.c552
-rw-r--r--lbx/lbxserve.h173
-rw-r--r--lbx/lbxsquish.c152
-rw-r--r--lbx/lbxsrvopts.h78
-rw-r--r--lbx/lbxswap.c858
-rw-r--r--lbx/lbxtables.c33
-rw-r--r--lbx/lbxtags.c238
-rw-r--r--lbx/lbxtags.h119
-rw-r--r--lbx/lbxzerorep.c416
-rw-r--r--mfb/fastblt.h118
-rw-r--r--mfb/maskbits.c9871
-rw-r--r--mfb/maskbits.h711
-rw-r--r--mfb/mergerop.h186
-rw-r--r--mfb/mfb.h1250
-rw-r--r--mfb/mfbbitblt.c485
-rw-r--r--mfb/mfbblt.c587
-rw-r--r--mfb/mfbbres.c365
-rw-r--r--mfb/mfbbresd.c204
-rw-r--r--mfb/mfbbstore.c151
-rw-r--r--mfb/mfbclip.c268
-rw-r--r--mfb/mfbcmap.c198
-rw-r--r--mfb/mfbfillarc.c328
-rw-r--r--mfb/mfbfillrct.c224
-rw-r--r--mfb/mfbfillsp.c1024
-rw-r--r--mfb/mfbfont.c72
-rw-r--r--mfb/mfbgc.c1527
-rw-r--r--mfb/mfbgetsp.c154
-rw-r--r--mfb/mfbhrzvert.c172
-rw-r--r--mfb/mfbimage.c173
-rw-r--r--mfb/mfbimggblt.c440
-rw-r--r--mfb/mfbline.c750
-rw-r--r--mfb/mfbmisc.c91
-rw-r--r--mfb/mfbpixmap.c294
-rw-r--r--mfb/mfbply1rct.c255
-rw-r--r--mfb/mfbplygblt.c387
-rw-r--r--mfb/mfbpntarea.c296
-rw-r--r--mfb/mfbpntwin.c123
-rw-r--r--mfb/mfbpolypnt.c140
-rw-r--r--mfb/mfbpushpxl.c278
-rw-r--r--mfb/mfbscrclse.c59
-rw-r--r--mfb/mfbscrinit.c166
-rw-r--r--mfb/mfbsetsp.c277
-rw-r--r--mfb/mfbtegblt.c419
-rw-r--r--mfb/mfbtile.c230
-rw-r--r--mfb/mfbwindow.c338
-rw-r--r--mfb/mfbzerarc.c253
-rw-r--r--mi/cbrt.c39
-rw-r--r--mi/mi.h748
-rw-r--r--mi/miarc.c3654
-rw-r--r--mi/mibitblt.c818
-rw-r--r--mi/mibstore.c3823
-rw-r--r--mi/mibstore.h62
-rw-r--r--mi/mibstorest.h91
-rw-r--r--mi/miclipn.c73
-rw-r--r--mi/micursor.c71
-rw-r--r--mi/midash.c310
-rw-r--r--mi/midispcur.c614
-rw-r--r--mi/mieq.c191
-rw-r--r--mi/miexpose.c827
-rw-r--r--mi/mifillarc.c810
-rw-r--r--mi/mifillarc.h223
-rw-r--r--mi/mifillrct.c139
-rw-r--r--mi/mifpoly.h108
-rw-r--r--mi/mifpolycon.c277
-rw-r--r--mi/migc.c295
-rw-r--r--mi/migc.h113
-rw-r--r--mi/miglblt.c248
-rw-r--r--mi/miinitext.c246
-rw-r--r--mi/miline.h167
-rw-r--r--mi/mipointer.c498
-rw-r--r--mi/mipointer.h122
-rw-r--r--mi/mipointrst.h62
-rw-r--r--mi/mipoly.c124
-rw-r--r--mi/mipoly.h228
-rw-r--r--mi/mipolycon.c245
-rw-r--r--mi/mipolygen.c226
-rw-r--r--mi/mipolypnt.c119
-rw-r--r--mi/mipolyrect.c187
-rw-r--r--mi/mipolyseg.c79
-rw-r--r--mi/mipolytext.c196
-rw-r--r--mi/mipolyutil.c398
-rw-r--r--mi/mipushpxl.c197
-rw-r--r--mi/miregion.c2419
-rw-r--r--mi/miscanfill.h144
-rw-r--r--mi/miscrinit.c288
-rw-r--r--mi/mispans.c554
-rw-r--r--mi/mispans.h132
-rw-r--r--mi/misprite.c2067
-rw-r--r--mi/misprite.h111
-rw-r--r--mi/mispritest.h110
-rw-r--r--mi/mistruct.h63
-rw-r--r--mi/mivalidate.h51
-rw-r--r--mi/mivaltree.c729
-rw-r--r--mi/miwideline.c2203
-rw-r--r--mi/miwideline.h244
-rw-r--r--mi/miwindow.c1144
-rw-r--r--mi/mizerarc.c848
-rw-r--r--mi/mizerarc.h137
-rw-r--r--mi/mizerline.c960
-rw-r--r--os/WaitFor.c613
-rw-r--r--os/access.c1232
-rw-r--r--os/auth.c411
-rw-r--r--os/connection.c1281
-rw-r--r--os/io.c1262
-rw-r--r--os/k5auth.c796
-rw-r--r--os/lbxio.c585
-rw-r--r--os/mitauth.c193
-rw-r--r--os/oscolor.c294
-rw-r--r--os/osdep.h186
-rw-r--r--os/osinit.c200
-rw-r--r--os/rpcauth.c202
-rw-r--r--os/secauth.c201
-rw-r--r--os/utils.c1105
-rw-r--r--os/xdmauth.c518
-rw-r--r--os/xdmcp.c1341
-rw-r--r--record/record.c3021
-rw-r--r--record/set.c702
-rw-r--r--record/set.h159
-rw-r--r--xkb/README.compiled13
-rw-r--r--xkb/XKBAlloc.c587
-rw-r--r--xkb/XKBGAlloc.c1377
-rw-r--r--xkb/XKBMAlloc.c1077
-rw-r--r--xkb/XKBMisc.c1071
-rw-r--r--xkb/ddxBeep.c359
-rw-r--r--xkb/ddxConfig.c217
-rw-r--r--xkb/ddxCtrls.c133
-rw-r--r--xkb/ddxDevBtn.c104
-rw-r--r--xkb/ddxFakeBtn.c62
-rw-r--r--xkb/ddxFakeMtn.c76
-rw-r--r--xkb/ddxInit.c48
-rw-r--r--xkb/ddxKeyClick.c54
-rw-r--r--xkb/ddxKillSrv.c51
-rw-r--r--xkb/ddxLEDs.c82
-rw-r--r--xkb/ddxList.c309
-rw-r--r--xkb/ddxLoad.c495
-rw-r--r--xkb/ddxVT.c50
-rw-r--r--xkb/maprules.c1382
-rw-r--r--xkb/xkb.c6929
-rw-r--r--xkb/xkbAccessX.c856
-rw-r--r--xkb/xkbActions.c1462
-rw-r--r--xkb/xkbDflts.h519
-rw-r--r--xkb/xkbEvents.c1154
-rw-r--r--xkb/xkbInit.c994
-rw-r--r--xkb/xkbLEDs.c1212
-rw-r--r--xkb/xkbPrKeyEv.c193
-rw-r--r--xkb/xkbPrOtherEv.c88
-rw-r--r--xkb/xkbSwap.c759
-rw-r--r--xkb/xkbUtils.c1141
-rw-r--r--xkb/xkbconfig.c1394
-rw-r--r--xkb/xkberrs.c70
-rw-r--r--xkb/xkbfmisc.c716
-rw-r--r--xkb/xkbout.c1216
-rw-r--r--xkb/xkbtext.c1700
-rw-r--r--xkb/xkmread.c1481
609 files changed, 262690 insertions, 0 deletions
diff --git a/Xext/EVI.c b/Xext/EVI.c
new file mode 100644
index 000000000..8ccc31af2
--- /dev/null
+++ b/Xext/EVI.c
@@ -0,0 +1,179 @@
+/* $Xorg: EVI.c,v 1.3 2000/08/17 19:47:55 cpqbld Exp $ */
+/************************************************************
+Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+********************************************************/
+#include "X.h"
+#include "Xproto.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "dix.h"
+#define _XEVI_SERVER_
+#include "XEVIstr.h"
+#include "EVIstruct.h"
+static unsigned char XEVIReqCode = 0;
+static EviPrivPtr eviPriv;
+static int
+ProcEVIQueryVersion(ClientPtr client)
+{
+ REQUEST(xEVIQueryVersionReq);
+ xEVIQueryVersionReply rep;
+ register int n;
+ REQUEST_SIZE_MATCH (xEVIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = XEVI_MAJOR_VERSION;
+ rep.minorVersion = XEVI_MAJOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof (xEVIQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+#define swapEviInfo(eviInfo, l) \
+{ \
+ int l1 = l; \
+ xExtendedVisualInfo *eviInfo1 = eviInfo; \
+ while (l1-- > 0) { \
+ swapl(&eviInfo1->core_visual_id, n); \
+ swapl(&eviInfo1->transparency_value, n); \
+ swaps(&eviInfo1->num_colormap_conflicts, n); \
+ eviInfo1++; \
+ } \
+}
+#define swapVisual(visual, l) \
+{ \
+ int l1 = l; \
+ VisualID32 *visual1 = visual; \
+ while (l1-- > 0) { \
+ swapl(visual1, n); \
+ visual1++; \
+ } \
+}
+static int
+ProcEVIGetVisualInfo(ClientPtr client)
+{
+ REQUEST(xEVIGetVisualInfoReq);
+ xEVIGetVisualInfoReply rep;
+ int n, n_conflict, n_info, sz_info, sz_conflict;
+ VisualID32 *conflict;
+ xExtendedVisualInfo *eviInfo;
+ int status;
+ REQUEST_FIXED_SIZE(xEVIGetVisualInfoReq, stuff->n_visual * sz_VisualID32);
+ status = eviPriv->getVisualInfo((VisualID32 *)&stuff[1], (int)stuff->n_visual,
+ &eviInfo, &n_info, &conflict, &n_conflict);
+ if (status != Success)
+ return status;
+ sz_info = n_info * sz_xExtendedVisualInfo;
+ sz_conflict = n_conflict * sz_VisualID32;
+ rep.type = X_Reply;
+ rep.n_info = n_info;
+ rep.n_conflicts = n_conflict;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (sz_info + sz_conflict) >> 2;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.n_info, n);
+ swapl(&rep.n_conflicts, n);
+ swapEviInfo(eviInfo, n_info);
+ swapVisual(conflict, n_conflict);
+ }
+ WriteToClient(client, sz_xEVIGetVisualInfoReply, (char *)&rep);
+ WriteToClient(client, sz_info, (char *)eviInfo);
+ WriteToClient(client, sz_conflict, (char *)conflict);
+ eviPriv->freeVisualInfo(eviInfo, conflict);
+ return (client->noClientException);
+}
+static int
+ProcEVIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_EVIQueryVersion:
+ return ProcEVIQueryVersion (client);
+ case X_EVIGetVisualInfo:
+ return ProcEVIGetVisualInfo (client);
+ default:
+ return BadRequest;
+ }
+}
+static int
+SProcEVIQueryVersion(client)
+ClientPtr client;
+{
+ REQUEST(xEVIQueryVersionReq);
+ int n;
+ swaps(&stuff->length, n);
+ return ProcEVIQueryVersion(client);
+}
+static int
+SProcEVIGetVisualInfo(ClientPtr client)
+{
+ register int n;
+ REQUEST(xEVIGetVisualInfoReq);
+ swaps(&stuff->length, n);
+ return ProcEVIGetVisualInfo(client);
+}
+static int
+SProcEVIDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_EVIQueryVersion:
+ return SProcEVIQueryVersion (client);
+ case X_EVIGetVisualInfo:
+ return SProcEVIGetVisualInfo (client);
+ default:
+ return BadRequest;
+ }
+}
+/*ARGSUSED*/
+static void
+EVIResetProc(ExtensionEntry *extEntry)
+{
+ eviDDXReset();
+}
+/****************
+ * XEVIExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+void
+EVIExtensionInit(void)
+{
+ ExtensionEntry *extEntry, *AddExtension();
+ if (extEntry = AddExtension(EVINAME, 0, 0,
+ ProcEVIDispatch,
+ SProcEVIDispatch,
+ EVIResetProc, StandardMinorOpcode))
+ {
+ XEVIReqCode = (unsigned char)extEntry->base;
+ eviPriv = eviDDXInit();
+ }
+}
diff --git a/Xext/EVIstruct.h b/Xext/EVIstruct.h
new file mode 100644
index 000000000..9bb24b0d2
--- /dev/null
+++ b/Xext/EVIstruct.h
@@ -0,0 +1,53 @@
+/* $Xorg: EVIstruct.h,v 1.3 2000/08/17 19:47:55 cpqbld Exp $ */
+/************************************************************
+Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+********************************************************/
+#ifndef EVI_STRUCT_H
+#define EVI_STRUCT_H
+/*
+ ******************************************************************************
+ ** Per-ddx data
+ ******************************************************************************
+ */
+typedef int (*GetVisualInfoProc)(
+#if NeedNestedPrototypes
+ VisualID32*,
+ int,
+ xExtendedVisualInfo**,
+ int*,
+ VisualID32**,
+ int*
+#endif
+);
+typedef void (*FreeVisualInfoProc)(
+#if NeedNestedPrototypes
+ xExtendedVisualInfo*,
+ VisualID32*
+#endif
+);
+typedef struct _EviPrivRec {
+ GetVisualInfoProc getVisualInfo;
+ FreeVisualInfoProc freeVisualInfo;
+} EviPrivRec, *EviPrivPtr;
+extern EviPrivPtr eviDDXInit();
+extern void eviDDXReset();
+#endif /* EVI_STRUCT_H */
diff --git a/Xext/README.xtest1-ddx b/Xext/README.xtest1-ddx
new file mode 100644
index 000000000..bdf7943b7
--- /dev/null
+++ b/Xext/README.xtest1-ddx
@@ -0,0 +1,90 @@
+There are several code fragments that need to be placed in the device
+dependent part of the server. These are described below. These code
+fragments are device and implementation dependent.
+
+This code fragment should go in your ddx InitInput() routine:
+
+#ifdef XTESTEXT1
+extern KeyCode xtest_command_key;
+#endif
+
+#ifdef XTESTEXT1
+ xtest_command_key = <whatever-is-a-good-keycode-for-your-keyboard>;
+#endif
+
+This code fragment should go at the front of the file that handles
+keyboards:
+
+#ifdef XTESTEXT1
+/*
+ * defined in xtestext1di.c
+ */
+extern int on_steal_input;
+extern Bool XTestStealKeyData();
+#endif XTESTEXT1
+
+This code fragment should go in the function that parses input from the
+keyboard or pointer after you know what input action has occurred, but before
+you have told the server about it. If conditionalizes the actual function
+call to pass the information on:
+
+#ifdef XTESTEXT1
+ if (!on_steal_input ||
+ XTestStealKeyData(code, direction, dev_type, x, y))
+#endif /* XTESTEXT1 */
+ handle_device_event(...);
+
+This code fragment should go in the function that handles mouse motion after
+you have figured out how much the mouse has moved:
+
+#ifdef XTESTEXT1
+ if (on_steal_input)
+ XTestStealMotionData(dx, dy, dev, x, y);
+#endif XTESTEXT1
+
+
+This code fragment should go at the front of the os-specific code where
+you wait (by doing a select on the socket in our implementation) for
+something to happen:
+
+#ifdef XTESTEXT1
+extern int playback_on;
+void XTestComputeWaitTime();
+#endif XTESTEXT1
+
+These code fragments should go in the os-specific code on both sides of
+where you wait (by doing a select on the socket in our implementation)
+for something to happen:
+
+#ifdef XTESTEXT1
+ if (playback_on)
+ XTestComputeWaitTime(wt = &waittime);
+#endif XTESTEXT1
+ ... code to do select ...
+ WakeupHandler(i, LastSelectMask);
+#ifdef XTESTEXT1
+ if (playback_on)
+ i = XTestProcessInputAction(i, &waittime);
+#endif XTESTEXT1
+
+
+You also need to implement the following routines (documentation
+is needed; for now, see server/ddx/hp/hp/x_hil.c):
+
+void
+XTestGenerateEvent(dev_type, keycode, keystate, mousex, mousey)
+ int dev_type;
+ int keycode;
+ int keystate;
+ int mousex;
+ int mousey;
+
+void
+XTestGetPointerPos(fmousex, fmousey)
+ short *fmousex, *fmousey;
+
+void
+XTestJumpPointer(jx, jy, dev_type)
+ int jx;
+ int jy;
+ int dev_type;
diff --git a/Xext/SecurityPolicy b/Xext/SecurityPolicy
new file mode 100644
index 000000000..cc521c263
--- /dev/null
+++ b/Xext/SecurityPolicy
@@ -0,0 +1,88 @@
+version-1
+
+# $Xorg: SecurityPolicy,v 1.3 2000/08/17 19:47:56 cpqbld Exp $
+
+# The site policy fields are interpreted by the XC-QUERY-SECURITY-1
+# authorization protocol. The values are arbitrary and site-specific.
+# Refer to the Security Extension Specification for the usage of the policies.
+#sitepolicy A
+#sitepolicy B
+#sitepolicy C
+
+# Property access rules:
+# property <property> <window> <permissions>
+# <window> ::= any | root | <propertyselector>
+# <propertyselector> ::= <property> | <property>=<value>
+# <permissions> :== [ <operation> | <action> | <space> ]*
+# <operation> :== r | w | d
+# r read
+# w write
+# d delete
+# <action> :== a | i | e
+# a allow
+# i ignore
+# e error
+
+# Allow reading of application resources, but not writing.
+property RESOURCE_MANAGER root ar iw
+property SCREEN_RESOURCES root ar iw
+
+# Ignore attempts to use cut buffers. Giving errors causes apps to crash,
+# and allowing access may give away too much information.
+property CUT_BUFFER0 root irw
+property CUT_BUFFER1 root irw
+property CUT_BUFFER2 root irw
+property CUT_BUFFER3 root irw
+property CUT_BUFFER4 root irw
+property CUT_BUFFER5 root irw
+property CUT_BUFFER6 root irw
+property CUT_BUFFER7 root irw
+
+# If you are using Motif, you probably want these.
+property _MOTIF_DEFAULT_BINDINGS root ar iw
+property _MOTIF_DRAG_WINDOW root ar iw
+property _MOTIF_DRAG_TARGETS any ar iw
+property _MOTIF_DRAG_ATOMS any ar iw
+property _MOTIF_DRAG_ATOM_PAIRS any ar iw
+
+# If you are running CDE you also need these
+property _MOTIF_WM_INFO root arw
+property TT_SESSION root irw
+property WM_ICON_SIZE root irw
+property "SDT Pixel Set" any irw
+
+# The next two rules let xwininfo -tree work when untrusted.
+property WM_NAME any ar
+
+# Allow read of WM_CLASS, but only for windows with WM_NAME.
+# This might be more restrictive than necessary, but demonstrates
+# the <required property> facility, and is also an attempt to
+# say "top level windows only."
+property WM_CLASS WM_NAME ar
+
+# These next three let xlsclients work untrusted. Think carefully
+# before including these; giving away the client machine name and command
+# may be exposing too much.
+property WM_STATE WM_NAME ar
+property WM_CLIENT_MACHINE WM_NAME ar
+property WM_COMMAND WM_NAME ar
+
+# To let untrusted clients use the standard colormaps created by
+# xstdcmap, include these lines.
+property RGB_DEFAULT_MAP root ar
+property RGB_BEST_MAP root ar
+property RGB_RED_MAP root ar
+property RGB_GREEN_MAP root ar
+property RGB_BLUE_MAP root ar
+property RGB_GRAY_MAP root ar
+
+# To let untrusted clients use the color management database created
+# by xcmsdb, include these lines.
+property XDCCC_LINEAR_RGB_CORRECTION root ar
+property XDCCC_LINEAR_RGB_MATRICES root ar
+property XDCCC_GRAY_SCREENWHITEPOINT root ar
+property XDCCC_GRAY_CORRECTION root ar
+
+# To let untrusted clients use the overlay visuals that many vendors
+# support, include this line.
+property SERVER_OVERLAY_VISUALS root ar
diff --git a/Xext/appgroup.c b/Xext/appgroup.c
new file mode 100644
index 000000000..71e74da38
--- /dev/null
+++ b/Xext/appgroup.c
@@ -0,0 +1,810 @@
+/*
+Copyright 1996, 1998, 2001 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+*/
+/* $Xorg: appgroup.c,v 1.6 2001/02/09 02:04:32 xorgcvs Exp $ */
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "servermd.h"
+#define _XAG_SERVER_
+#include "Xagstr.h"
+#define _SECURITY_SERVER
+#include "security.h"
+#include "Xfuncproto.h"
+
+#define XSERV_t
+#include <X11/Xtrans.h>
+#include "../os/osdep.h"
+
+#include <stdio.h>
+
+typedef struct _AppGroupRec {
+ struct _AppGroupRec* next;
+ XID appgroupId;
+ ClientPtr* clients;
+ int nclients;
+ ClientPtr leader;
+ Bool single_screen;
+ Window default_root;
+ VisualID root_visual;
+ Colormap default_colormap;
+ Pixel black_pixel;
+ Pixel white_pixel;
+ xConnSetupPrefix connSetupPrefix;
+ char* ConnectionInfo;
+} AppGroupRec, *AppGroupPtr;
+
+static int ProcXagDispatch (), SProcXagDispatch ();
+static void XagResetProc ();
+
+static unsigned char XagReqCode = 0;
+static int XagErrorBase;
+static int XagCallbackRefCount = 0;
+
+static RESTYPE RT_APPGROUP;
+static AppGroupPtr appGrpList = NULL;
+
+extern WindowPtr* WindowTable;
+extern xConnSetupPrefix connSetupPrefix;
+extern char* ConnectionInfo;
+
+static
+int XagAppGroupFree (what, id)
+ pointer what;
+ XID id; /* unused */
+{
+ int i;
+ AppGroupPtr pAppGrp = (AppGroupPtr) what;
+
+ if (pAppGrp->leader)
+ for (i = 0; i < pAppGrp->nclients; i++) {
+ pAppGrp->clients[i]->appgroup = NULL;
+ CloseDownClient (pAppGrp->clients[i]);
+ }
+
+ if (pAppGrp == appGrpList)
+ appGrpList = appGrpList->next;
+ else {
+ AppGroupPtr tpAppGrp;
+ for (tpAppGrp = appGrpList;
+ tpAppGrp->next != NULL;
+ tpAppGrp = tpAppGrp->next) {
+ if (tpAppGrp->next == pAppGrp) {
+ tpAppGrp->next = tpAppGrp->next->next;
+ break;
+ }
+ }
+ }
+ (void) xfree (pAppGrp->clients);
+ (void) xfree (pAppGrp->ConnectionInfo);
+ (void) xfree (what);
+ return Success;
+}
+
+/* static */
+void XagClientStateChange (pcbl, nulldata, calldata)
+ CallbackListPtr* pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ SecurityAuthorizationPtr pAuth;
+ NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
+ ClientPtr pClient = pci->client;
+ AppGroupPtr pAppGrp;
+ XID authId;
+
+ if (!pClient->appgroup) {
+ switch (pClient->clientState) {
+
+ case ClientStateAuthenticating:
+ case ClientStateRunning:
+ case ClientStateCheckingSecurity:
+ return;
+
+ case ClientStateInitial:
+ case ClientStateCheckedSecurity:
+ /*
+ * If the client is connecting via a firewall proxy (which
+ * uses XC-QUERY-SECURITY-1, then the authId is available
+ * during ClientStateCheckedSecurity, otherwise it's
+ * available during ClientStateInitial.
+ *
+ * Don't get it from pClient because can't guarantee the order
+ * of the callbacks and the security extension might not have
+ * plugged it in yet.
+ */
+ authId = AuthorizationIDOfClient(pClient);
+ break;
+
+ case ClientStateGone:
+ case ClientStateRetained:
+ /*
+ * Don't get if from AuthorizationIDOfClient because can't
+ * guarantee the order of the callbacks and the security
+ * extension may have torn down the client's private data
+ */
+ authId = pClient->authId;
+ break;
+ }
+
+ if (authId == None)
+ return;
+
+ pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(pClient,
+ authId, SecurityAuthorizationResType, SecurityReadAccess);
+
+ if (pAuth == NULL)
+ return;
+
+ for (pAppGrp = appGrpList; pAppGrp != NULL; pAppGrp = pAppGrp->next)
+ if (pAppGrp->appgroupId == pAuth->group) break;
+ } else {
+ pAppGrp = pClient->appgroup;
+ }
+
+ if (!pAppGrp)
+ return;
+
+ switch (pClient->clientState) {
+ case ClientStateAuthenticating:
+ case ClientStateRunning:
+ case ClientStateCheckingSecurity:
+ break;
+
+ case ClientStateInitial:
+ case ClientStateCheckedSecurity:
+ /* see the comment above about Initial vs. CheckedSecurity */
+ {
+ /* if this client already in AppGroup, don't add it again */
+ int i;
+ for (i = 0; i < pAppGrp->nclients; i++)
+ if (pClient == pAppGrp->clients[i]) return;
+ }
+ pAppGrp->clients = (ClientPtr*) xrealloc (pAppGrp->clients,
+ ++pAppGrp->nclients * sizeof (ClientPtr));
+ pAppGrp->clients[pAppGrp->nclients - 1] = pClient;
+ pClient->appgroup = pAppGrp;
+ break;
+
+ case ClientStateGone:
+ case ClientStateRetained: /* client disconnected, dump it */
+ {
+ int i;
+ for (i = 0; i < pAppGrp->nclients; i++)
+ if (pAppGrp->clients[i] == pClient) {
+ pAppGrp->clients[i] = NULL;
+ break;
+ }
+ for (i = 0; i < pAppGrp->nclients; i++)
+ if (pAppGrp->clients[i] == NULL && i + 1 < pAppGrp->nclients)
+ pAppGrp->clients[i] = pAppGrp->clients[i + 1];
+ pAppGrp->nclients--;
+ }
+ pClient->appgroup = NULL; /* redundant, pClient will be freed */
+ break;
+ }
+}
+
+void
+XagExtensionInit ()
+{
+ ExtensionEntry* extEntry;
+
+ if (extEntry = AddExtension (XAGNAME,
+ 0,
+ XagNumberErrors,
+ ProcXagDispatch,
+ SProcXagDispatch,
+ XagResetProc,
+ StandardMinorOpcode)) {
+ XagReqCode = (unsigned char)extEntry->base;
+ XagErrorBase = extEntry->errorBase;
+ RT_APPGROUP = CreateNewResourceType (XagAppGroupFree);
+ }
+}
+
+/*ARGSUSED*/
+static
+void XagResetProc (extEntry)
+ ExtensionEntry* extEntry;
+{
+ DeleteCallback (&ClientStateCallback, XagClientStateChange, NULL);
+ XagCallbackRefCount = 0;
+ while (appGrpList) XagAppGroupFree ((pointer) appGrpList, 0);
+}
+
+static
+int ProcXagQueryVersion (client)
+ register ClientPtr client;
+{
+ REQUEST (xXagQueryVersionReq);
+ xXagQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xXagQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequence_number = client->sequence;
+ rep.server_major_version = XAG_MAJOR_VERSION;
+ rep.server_minor_version = XAG_MINOR_VERSION;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ swaps (&rep.server_major_version, n);
+ swaps (&rep.server_minor_version, n);
+ }
+ WriteToClient (client, sizeof (xXagQueryVersionReply), (char *)&rep);
+ return client->noClientException;
+}
+
+static
+void ProcessAttr (pAppGrp, client, attrib_mask, attribs)
+ AppGroupPtr pAppGrp;
+ ClientPtr client;
+ unsigned int attrib_mask;
+ CARD32* attribs;
+{
+ int i;
+
+ for (i = 0; i <= XagNappGroupLeader; i++) {
+ switch (attrib_mask & (1 << i)) {
+ case XagSingleScreenMask:
+ pAppGrp->single_screen = *attribs;
+ break;
+ case XagDefaultRootMask:
+ pAppGrp->default_root = *attribs;
+ break;
+ case XagRootVisualMask:
+ pAppGrp->root_visual = *attribs;
+ break;
+ case XagDefaultColormapMask:
+ pAppGrp->default_colormap = *attribs;
+ break;
+ case XagBlackPixelMask:
+ pAppGrp->black_pixel = *attribs;
+ break;
+ case XagWhitePixelMask:
+ pAppGrp->white_pixel = *attribs;
+ break;
+ case XagAppGroupLeaderMask:
+ pAppGrp->leader = client;
+ break;
+ default: continue;
+ }
+ attribs++;
+ }
+}
+
+static
+void CreateConnectionInfo (pAppGrp)
+ AppGroupPtr pAppGrp;
+{
+ extern int connBlockScreenStart;
+ xConnSetup *setup = (xConnSetup*) ConnectionInfo;
+ xWindowRoot* rootp;
+ xWindowRoot* roots[MAXSCREENS];
+ unsigned int rootlens[MAXSCREENS];
+ xDepth* depth;
+ int olen;
+ int snum, i;
+
+ rootp = (xWindowRoot*) (ConnectionInfo + connBlockScreenStart);
+ for (snum = 0; snum < screenInfo.numScreens; snum++) {
+
+ rootlens[snum] = sizeof (xWindowRoot);
+ roots[snum] = rootp;
+
+ depth = (xDepth*) (rootp + 1);
+ for (i = 0; i < rootp->nDepths; i++) {
+ rootlens[snum] += sizeof (xDepth) +
+ depth->nVisuals * sizeof (xVisualType);
+ depth = (xDepth *)(((char*)(depth + 1)) +
+ depth->nVisuals * sizeof (xVisualType));
+ }
+ rootp = (xWindowRoot*) depth;
+ }
+ snum = 0;
+ if (pAppGrp->default_root) {
+ for (; snum < screenInfo.numVideoScreens; snum++) {
+ if (roots[snum]->windowId == pAppGrp->default_root)
+ break;
+ }
+ }
+ olen = connBlockScreenStart + rootlens[snum];
+ for (i = screenInfo.numVideoScreens; i < screenInfo.numScreens; i++)
+ olen += rootlens[i];
+ pAppGrp->ConnectionInfo = (char*) xalloc (olen);
+ if (!pAppGrp->ConnectionInfo)
+ return;
+ memmove (pAppGrp->ConnectionInfo, ConnectionInfo, connBlockScreenStart);
+ ((xConnSetup*) (pAppGrp->ConnectionInfo))->numRoots =
+ 1 + screenInfo.numScreens - screenInfo.numVideoScreens;
+ memmove (pAppGrp->ConnectionInfo + connBlockScreenStart,
+ (void*) roots[snum], rootlens[snum]);
+ rootp = (xWindowRoot*) (pAppGrp->ConnectionInfo + connBlockScreenStart);
+ if (pAppGrp->default_colormap) {
+ rootp->defaultColormap = pAppGrp->default_colormap;
+ rootp->whitePixel = pAppGrp->white_pixel;
+ rootp->blackPixel = pAppGrp->black_pixel;
+ }
+ if (pAppGrp->root_visual)
+ rootp->rootVisualID = pAppGrp->root_visual;
+ rootp = (xWindowRoot*) (((char*)rootp) + rootlens[snum]);
+ for (i = screenInfo.numVideoScreens; i < screenInfo.numScreens; i++) {
+ memmove ((void*) rootp, (void*) roots[i], rootlens[i]);
+ rootp = (xWindowRoot*) (((char*) rootp) + rootlens[i]);
+ }
+ pAppGrp->connSetupPrefix = connSetupPrefix;
+ pAppGrp->connSetupPrefix.length = olen >> 2;
+}
+
+static
+AppGroupPtr CreateAppGroup (client, appgroupId, attrib_mask, attribs)
+ ClientPtr client;
+ XID appgroupId;
+ unsigned int attrib_mask;
+ CARD32* attribs;
+{
+ AppGroupPtr pAppGrp;
+ int i;
+
+ pAppGrp = (AppGroupPtr) xalloc (sizeof(AppGroupRec));
+ if (pAppGrp) {
+ pAppGrp->next = appGrpList;
+ appGrpList = pAppGrp;
+ pAppGrp->appgroupId = appgroupId;
+ pAppGrp->clients = (ClientPtr*) xalloc (0);
+ pAppGrp->nclients = 0;
+ pAppGrp->leader = NULL;
+ pAppGrp->default_root = 0;
+ pAppGrp->root_visual = 0;
+ pAppGrp->default_colormap = 0;
+ pAppGrp->black_pixel = -1;
+ pAppGrp->white_pixel = -1;
+ pAppGrp->ConnectionInfo = NULL;
+ ProcessAttr (pAppGrp, client, attrib_mask, attribs);
+ }
+ return pAppGrp;
+}
+
+static
+int AttrValidate (client, attrib_mask, pAppGrp)
+ ClientPtr client;
+ int attrib_mask;
+ AppGroupPtr pAppGrp;
+{
+ WindowPtr pWin;
+ int idepth, ivids, found;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ ColormapPtr pColormap;
+
+ pWin = LookupWindow (pAppGrp->default_root, client);
+ /* XXX check that pWin is not NULL */
+ pScreen = pWin->drawable.pScreen;
+ if (WindowTable[pScreen->myNum]->drawable.id != pAppGrp->default_root)
+ return BadWindow;
+ pDepth = pScreen->allowedDepths;
+ if (pAppGrp->root_visual) {
+ found = FALSE;
+ for (idepth = 0; idepth < pScreen->numDepths; idepth++, pDepth++) {
+ for (ivids = 0; ivids < pDepth->numVids; ivids++) {
+ if (pAppGrp->root_visual == pDepth->vids[ivids]) {
+ found = TRUE;
+ break;
+ }
+ }
+ }
+ if (!found)
+ return BadMatch;
+ }
+ if (pAppGrp->default_colormap) {
+
+ pColormap = (ColormapPtr)LookupIDByType (pAppGrp->default_colormap, RT_COLORMAP);
+ /* XXX check that pColormap is not NULL */
+ if (pColormap->pScreen != pScreen)
+ return BadColor;
+ if (pColormap->pVisual->vid != (pAppGrp->root_visual ? pAppGrp->root_visual : pScreen->rootVisual))
+ return BadMatch;
+ }
+ return client->noClientException;
+}
+
+/* static */
+int ProcXagCreate (client)
+ register ClientPtr client;
+{
+ REQUEST (xXagCreateReq);
+ AppGroupPtr pAppGrp;
+ int ret;
+
+ REQUEST_AT_LEAST_SIZE (xXagCreateReq);
+
+ LEGAL_NEW_RESOURCE (stuff->app_group, client);
+ pAppGrp = CreateAppGroup (client, stuff->app_group,
+ stuff->attrib_mask, (CARD32*) &stuff[1]);
+ if (!pAppGrp)
+ return BadAlloc;
+ ret = AttrValidate (client, stuff->attrib_mask, pAppGrp);
+ if (ret != Success) {
+ XagAppGroupFree ((pointer)pAppGrp, (XID)0);
+ return ret;
+ }
+ if (pAppGrp->single_screen) {
+ CreateConnectionInfo (pAppGrp);
+ if (!pAppGrp->ConnectionInfo)
+ return BadAlloc;
+ }
+ if (!AddResource (stuff->app_group, RT_APPGROUP, (pointer)pAppGrp))
+ return BadAlloc;
+ if (XagCallbackRefCount++ == 0)
+ (void) AddCallback (&ClientStateCallback, XagClientStateChange, NULL);
+ return client->noClientException;
+}
+
+/* static */
+int ProcXagDestroy (client)
+ register ClientPtr client;
+{
+ AppGroupPtr pAppGrp;
+ REQUEST (xXagDestroyReq);
+
+ REQUEST_SIZE_MATCH (xXagDestroyReq);
+ pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client,
+ (XID)stuff->app_group, RT_APPGROUP, SecurityReadAccess);
+ if (!pAppGrp) return XagBadAppGroup;
+ FreeResource ((XID)stuff->app_group, RT_NONE);
+ if (--XagCallbackRefCount == 0)
+ (void) DeleteCallback (&ClientStateCallback, XagClientStateChange, NULL);
+ return client->noClientException;
+}
+
+static
+int ProcXagGetAttr (client)
+ register ClientPtr client;
+{
+ AppGroupPtr pAppGrp;
+ REQUEST (xXagGetAttrReq);
+ xXagGetAttrReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH (xXagGetAttrReq);
+ pAppGrp = (AppGroupPtr)SecurityLookupIDByType (client,
+ (XID)stuff->app_group, RT_APPGROUP, SecurityReadAccess);
+ if (!pAppGrp) return XagBadAppGroup;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequence_number = client->sequence;
+ rep.default_root = pAppGrp->default_root;
+ rep.root_visual = pAppGrp->root_visual;
+ rep.default_colormap = pAppGrp->default_colormap;
+ rep.black_pixel = pAppGrp->black_pixel;
+ rep.white_pixel = pAppGrp->white_pixel;
+ rep.single_screen = pAppGrp->single_screen;
+ rep.app_group_leader = (pAppGrp->leader) ? 1 : 0;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ swapl (&rep.default_root, n);
+ swapl (&rep.root_visual, n);
+ swapl (&rep.default_colormap, n);
+ swapl (&rep.black_pixel, n);
+ swapl (&rep.white_pixel, n);
+ }
+ WriteToClient (client, sizeof (xXagGetAttrReply), (char *)&rep);
+ return client->noClientException;
+}
+
+static
+int ProcXagQuery (client)
+ register ClientPtr client;
+{
+ ClientPtr pClient;
+ AppGroupPtr pAppGrp;
+ REQUEST (xXagQueryReq);
+ int n;
+
+ REQUEST_SIZE_MATCH (xXagQueryReq);
+ pClient = LookupClient (stuff->resource, client);
+ for (pAppGrp = appGrpList; pAppGrp != NULL; pAppGrp = pAppGrp->next)
+ for (n = 0; n < pAppGrp->nclients; n++)
+ if (pAppGrp->clients[n] == pClient) {
+ xXagQueryReply rep;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequence_number = client->sequence;
+ rep.app_group = pAppGrp->appgroupId;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ swapl (&rep.app_group, n);
+ }
+ WriteToClient (client, sizeof (xXagQueryReply), (char *)&rep);
+ return client->noClientException;
+ }
+
+ return BadMatch;
+}
+
+static
+int ProcXagCreateAssoc (client)
+ register ClientPtr client;
+{
+ REQUEST (xXagCreateAssocReq);
+
+ REQUEST_SIZE_MATCH (xXagCreateAssocReq);
+#ifdef WIN32
+ if (stuff->window_type != XagWindowTypeWin32)
+#else
+ if (stuff->window_type != XagWindowTypeX11)
+#endif
+ return BadMatch;
+#ifdef WIN32 /* and Mac, etc */
+ if (!LocalClient (client))
+ return BadAccess;
+#endif
+
+/* Macintosh, OS/2, and MS-Windows servers have some work to do here */
+
+ return client->noClientException;
+}
+
+static
+int ProcXagDestroyAssoc (client)
+ register ClientPtr client;
+{
+ REQUEST (xXagDestroyAssocReq);
+
+ REQUEST_SIZE_MATCH (xXagDestroyAssocReq);
+/* Macintosh, OS/2, and MS-Windows servers have some work to do here */
+ return client->noClientException;
+}
+
+static
+int ProcXagDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST (xReq);
+ switch (stuff->data)
+ {
+ case X_XagQueryVersion:
+ return ProcXagQueryVersion (client);
+ case X_XagCreate:
+ return ProcXagCreate (client);
+ case X_XagDestroy:
+ return ProcXagDestroy (client);
+ case X_XagGetAttr:
+ return ProcXagGetAttr (client);
+ case X_XagQuery:
+ return ProcXagQuery (client);
+ case X_XagCreateAssoc:
+ return ProcXagCreateAssoc (client);
+ case X_XagDestroyAssoc:
+ return ProcXagDestroyAssoc (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static
+int SProcXagQueryVersion (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xXagQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXagQueryVersion(client);
+}
+
+static
+int SProcXagCreate (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagCreateReq);
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xXagCreateReq);
+ swapl (&stuff->app_group, n);
+ swapl (&stuff->attrib_mask, n);
+ SwapRestL (stuff);
+ return ProcXagCreate (client);
+}
+
+static
+int SProcXagDestroy (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagDestroyReq);
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXagDestroyReq);
+ swapl (&stuff->app_group, n);
+ return ProcXagDestroy (client);
+}
+
+static
+int SProcXagGetAttr (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagGetAttrReq);
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXagGetAttrReq);
+ swapl (&stuff->app_group, n);
+ return ProcXagGetAttr (client);
+}
+
+static
+int SProcXagQuery (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagQueryReq);
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXagQueryReq);
+ swapl (&stuff->resource, n);
+ return ProcXagQuery (client);
+}
+
+static
+int SProcXagCreateAssoc (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagCreateAssocReq);
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXagCreateAssocReq);
+ swapl (&stuff->window, n);
+ swapl (&stuff->window_type, n);
+ swaps (&stuff->system_window_len, n);
+ return ProcXagCreateAssoc (client);
+}
+
+static
+int SProcXagDestroyAssoc (client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST (xXagDestroyAssocReq);
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXagDestroyAssocReq);
+ swapl (&stuff->window, n);
+ return ProcXagDestroyAssoc (client);
+}
+
+static
+int SProcXagDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XagQueryVersion:
+ return SProcXagQueryVersion (client);
+ case X_XagCreate:
+ return SProcXagCreate (client);
+ case X_XagDestroy:
+ return SProcXagDestroy (client);
+ case X_XagGetAttr:
+ return SProcXagGetAttr (client);
+ case X_XagQuery:
+ return SProcXagQuery (client);
+ case X_XagCreateAssoc:
+ return SProcXagCreateAssoc (client);
+ case X_XagDestroyAssoc:
+ return SProcXagDestroyAssoc (client);
+ default:
+ return BadRequest;
+ }
+}
+
+Colormap XagDefaultColormap (client)
+ ClientPtr client;
+{
+ return (client->appgroup ? client->appgroup->default_colormap : None);
+}
+
+VisualID XagRootVisual (client)
+ ClientPtr client;
+{
+ return (client->appgroup ? client->appgroup->root_visual : 0);
+}
+
+ClientPtr XagLeader (client)
+ ClientPtr client;
+{
+ return (client->appgroup ? client->appgroup->leader : NULL);
+}
+
+/*
+ * Return whether the Map request event should be sent to the appgroup leader.
+ * We don't want to send it to the leader when the window is on a different
+ * screen, e.g. a print screen.
+ */
+Bool XagIsControlledRoot (client, pParent)
+ ClientPtr client;
+ WindowPtr pParent;
+{
+ if (client->appgroup) {
+ if (client->appgroup->single_screen &&
+ pParent->drawable.id == client->appgroup->default_root)
+ return TRUE;
+ else if (!pParent->parent)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return FALSE;
+}
+
+void XagConnectionInfo (client, conn_prefix, conn_info, num_screen)
+ ClientPtr client;
+ xConnSetupPrefix** conn_prefix;
+ char** conn_info;
+ int* num_screen;
+{
+ if (client->appgroup && client->appgroup->ConnectionInfo) {
+ *conn_prefix = &client->appgroup->connSetupPrefix;
+ *conn_info = client->appgroup->ConnectionInfo;
+ *num_screen = ((xConnSetup*)(client->appgroup->ConnectionInfo))->numRoots;
+ }
+}
+
+XID XagId (client)
+ ClientPtr client;
+{
+ return (client->appgroup ? client->appgroup->appgroupId : 0);
+}
+
+void XagGetDeltaInfo (client, buf)
+ ClientPtr client;
+ CARD32* buf;
+{
+ *buf++ = (CARD32) client->appgroup->default_root;
+ *buf++ = (CARD32) client->appgroup->root_visual;
+ *buf++ = (CARD32) client->appgroup->default_colormap;
+ *buf++ = (CARD32) client->appgroup->black_pixel;
+ *buf = (CARD32) client->appgroup->white_pixel;
+}
+
+void XagCallClientStateChange (client)
+ ClientPtr client;
+{
+ if (appGrpList) {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ XagClientStateChange (NULL, NULL, (pointer)&clientinfo);
+ }
+}
diff --git a/Xext/bigreq.c b/Xext/bigreq.c
new file mode 100644
index 000000000..4f4bf5c02
--- /dev/null
+++ b/Xext/bigreq.c
@@ -0,0 +1,86 @@
+/* $Xorg: bigreq.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+/*
+
+Copyright 1992, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+*/
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "bigreqstr.h"
+
+static unsigned char XBigReqCode;
+static int ProcBigReqDispatch();
+static void BigReqResetProc();
+
+void
+BigReqExtensionInit()
+{
+ ExtensionEntry *extEntry, *AddExtension();
+
+ if (extEntry = AddExtension(XBigReqExtensionName, 0, 0,
+ ProcBigReqDispatch, ProcBigReqDispatch,
+ BigReqResetProc, StandardMinorOpcode))
+ XBigReqCode = (unsigned char)extEntry->base;
+ DeclareExtensionSecurity(XBigReqExtensionName, TRUE);
+}
+
+/*ARGSUSED*/
+static void
+BigReqResetProc (extEntry)
+ ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcBigReqDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xBigReqEnableReq);
+ xBigReqEnableReply rep;
+ register int n;
+
+ if (client->swapped) {
+ swaps(&stuff->length, n);
+ }
+ if (stuff->brReqType != X_BigReqEnable)
+ return BadRequest;
+ REQUEST_SIZE_MATCH(xBigReqEnableReq);
+ client->big_requests = TRUE;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.max_request_size = MAX_BIG_REQUEST_SIZE;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.max_request_size, n);
+ }
+ WriteToClient(client, sizeof(xBigReqEnableReply), (char *)&rep);
+ return(client->noClientException);
+}
diff --git a/Xext/cup.c b/Xext/cup.c
new file mode 100644
index 000000000..4e8cf66b4
--- /dev/null
+++ b/Xext/cup.c
@@ -0,0 +1,340 @@
+/* $Xorg: cup.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+/*
+
+Copyright 1997, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XCUP_SERVER_
+#include "Xcupstr.h"
+#include "Xfuncproto.h"
+
+#include "../os/osdep.h"
+
+static int ProcDispatch (), SProcDispatch ();
+static void ResetProc ();
+
+static unsigned char ReqCode = 0;
+static int ErrorBase;
+
+#if defined(WIN32) || defined(TESTWIN32)
+#define HAVE_SPECIAL_DESKTOP_COLORS
+#endif
+
+static xColorItem citems[] = {
+#ifndef HAVE_SPECIAL_DESKTOP_COLORS
+#define CUP_BLACK_PIXEL 0
+#define CUP_WHITE_PIXEL 1
+ /* pix red green blue */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 0xffff, 0xffff, 0xffff, 0, 0 }
+#else
+#ifndef WIN32
+ /*
+ This approximates the MS-Windows desktop colormap for testing
+ purposes but has black and white pixels in the typical Unix
+ locations, which should be switched if necessary if your system
+ has blackPixel and whitePixel swapped. No entries are provided
+ for colormap entries 254 and 255 because AllocColor/FindColor
+ will reuse entries zero and one.
+ */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 0xffff, 0xffff, 0xffff, 0, 0 },
+ { 2, 0x8000, 0, 0, 0, 0 },
+ { 3, 0, 0x8000, 0, 0, 0 },
+ { 4, 0x8000, 0x8000, 0, 0, 0 },
+ { 5, 0, 0, 0x8000, 0, 0 },
+ { 6, 0x8000, 0, 0x8000, 0, 0 },
+ { 7, 0, 0x8000, 0x8000, 0, 0 },
+ { 8, 0xc000, 0xc000, 0xc000, 0, 0 },
+ { 9, 0xc000, 0xdc00, 0xc000, 0, 0 },
+ { 246, 0xa000, 0xa000, 0xa000, 0, 0 },
+ { 247, 0x8000, 0x8000, 0x8000, 0, 0 },
+ { 248, 0xffff, 0, 0, 0, 0 },
+ { 249, 0, 0xffff, 0, 0, 0 },
+ { 250, 0xffff, 0xffff, 0, 0, 0 },
+ { 251, 0, 0, 0xffff, 0, 0 },
+ { 252, 0xffff, 0, 0xffff, 0, 0 },
+ { 253, 0, 0xffff, 0xffff, 0, 0 }
+#else
+ /*
+ this is the MS-Windows desktop, adjusted for X's 16-bit color
+ specifications.
+ */
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 0x8000, 0, 0, 0, 0 },
+ { 2, 0, 0x8000, 0, 0, 0 },
+ { 3, 0x8000, 0x8000, 0, 0, 0 },
+ { 4, 0, 0, 0x8000, 0, 0 },
+ { 5, 0x8000, 0, 0x8000, 0, 0 },
+ { 6, 0, 0x8000, 0x8000, 0, 0 },
+ { 7, 0xc000, 0xc000, 0xc000, 0, 0 },
+ { 8, 0xc000, 0xdc00, 0xc000, 0, 0 },
+ { 9, 0xa600, 0xca00, 0xf000, 0, 0 },
+ { 246, 0xff00, 0xfb00, 0xf000, 0, 0 },
+ { 247, 0xa000, 0xa000, 0xa400, 0, 0 },
+ { 248, 0x8000, 0x8000, 0x8000, 0, 0 },
+ { 249, 0xff00, 0, 0, 0, 0 },
+ { 250, 0, 0xff00, 0, 0, 0 },
+ { 251, 0xff00, 0xff00, 0, 0, 0 },
+ { 252, 0, 0, 0xff00, 0, 0 },
+ { 253, 0xff00, 0, 0xff00, 0, 0 },
+ { 254, 0, 0xff00, 0xff00, 0, 0 },
+ { 255, 0xff00, 0xff00, 0xff00, 0, 0 }
+#endif
+#endif
+};
+#define NUM_DESKTOP_COLORS (sizeof citems / sizeof citems[0])
+
+void
+XcupExtensionInit ()
+{
+ ExtensionEntry* extEntry;
+
+ if (extEntry = AddExtension (XCUPNAME,
+ 0,
+ XcupNumberErrors,
+ ProcDispatch,
+ SProcDispatch,
+ ResetProc,
+ StandardMinorOpcode)) {
+ ReqCode = (unsigned char)extEntry->base;
+ ErrorBase = extEntry->errorBase;
+ }
+
+ /* PC servers initialize the desktop colors (citems) here! */
+}
+
+/*ARGSUSED*/
+static
+void ResetProc (extEntry)
+ ExtensionEntry* extEntry;
+{
+}
+
+static
+int ProcQueryVersion (client)
+ register ClientPtr client;
+{
+ REQUEST (xXcupQueryVersionReq);
+ xXcupQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xXcupQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequence_number = client->sequence;
+ rep.server_major_version = XCUP_MAJOR_VERSION;
+ rep.server_minor_version = XCUP_MINOR_VERSION;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ swaps (&rep.server_major_version, n);
+ swaps (&rep.server_minor_version, n);
+ }
+ WriteToClient (client, sizeof (xXcupQueryVersionReply), (char *)&rep);
+ return client->noClientException;
+}
+
+static
+int ProcGetReservedColormapEntries (client)
+ register ClientPtr client;
+{
+ REQUEST (xXcupGetReservedColormapEntriesReq);
+ xXcupGetReservedColormapEntriesReply rep;
+ xColorItem* cptr;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xXcupGetReservedColormapEntriesReq);
+
+#ifndef HAVE_SPECIAL_DESKTOP_COLORS
+ citems[CUP_BLACK_PIXEL].pixel =
+ screenInfo.screens[stuff->screen]->blackPixel;
+ citems[CUP_WHITE_PIXEL].pixel =
+ screenInfo.screens[stuff->screen]->whitePixel;
+#endif
+
+ rep.type = X_Reply;
+ rep.sequence_number = client->sequence;
+ rep.length = NUM_DESKTOP_COLORS * 3;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ }
+ WriteToClient (client, sizeof (xXcupGetReservedColormapEntriesReply), (char *)&rep);
+ for (n = 0, cptr = citems; n < NUM_DESKTOP_COLORS; n++, cptr++) {
+ if (client->swapped) SwapColorItem (cptr);
+ WriteToClient (client, SIZEOF(xColorItem), (char *)cptr);
+ }
+ return client->noClientException;
+}
+
+static
+int ProcStoreColors (client)
+ register ClientPtr client;
+{
+ REQUEST (xXcupStoreColorsReq);
+ ColormapPtr pcmp;
+
+ REQUEST_AT_LEAST_SIZE (xXcupStoreColorsReq);
+ pcmp = (ColormapPtr) SecurityLookupIDByType (client, stuff->cmap,
+ RT_COLORMAP, SecurityWriteAccess);
+
+ if (pcmp) {
+ int ncolors, n;
+ xXcupStoreColorsReply rep;
+ xColorItem* cptr;
+ Pixel pixel;
+
+ if (!(pcmp->class & DynamicClass))
+ return BadMatch;
+
+ ncolors = (client->req_len << 2) - SIZEOF (xXcupStoreColorsReq);
+ if (ncolors % SIZEOF(xColorItem))
+ return BadLength;
+
+ ncolors /= SIZEOF (xColorItem);
+
+
+ for (n = 0, cptr = (xColorItem*) &stuff[1]; n < ncolors; n++) {
+ Pixel pixel = cptr->pixel;
+
+ if (AllocColor (pcmp,
+ &cptr->red, &cptr->green, &cptr->blue,
+ &pixel, client->index) == Success) {
+ cptr->pixel = pixel;
+ cptr->flags = 0x08;
+ } else
+ cptr->flags = 0;
+ cptr = (xColorItem*) (((char*)cptr) + SIZEOF(xColorItem));
+ }
+
+ rep.type = X_Reply;
+ rep.sequence_number = client->sequence;
+ rep.length = ncolors * 3;
+ if (client->swapped) {
+ swaps (&rep.sequence_number, n);
+ swapl (&rep.length, n);
+ }
+ WriteToClient (client, sizeof (xXcupGetReservedColormapEntriesReply), (char *)&rep);
+ for (n = 0, cptr = (xColorItem*) &stuff[1]; n < ncolors; n++) {
+ if (client->swapped) SwapColorItem (cptr);
+ WriteToClient (client, SIZEOF(xColorItem), (char *)cptr);
+ cptr = (xColorItem*) (((char*)cptr) + SIZEOF(xColorItem));
+ }
+ return client->noClientException;
+ } else {
+ client->errorValue = stuff->cmap;
+ return BadColor;
+ }
+}
+
+static
+int ProcDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST (xReq);
+ switch (stuff->data)
+ {
+ case X_XcupQueryVersion:
+ return ProcQueryVersion (client);
+ case X_XcupGetReservedColormapEntries:
+ return ProcGetReservedColormapEntries (client);
+ case X_XcupStoreColors:
+ return ProcStoreColors (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static
+int SProcQueryVersion (client)
+ register ClientPtr client;
+{
+ register int n;
+
+ REQUEST(xXcupQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcQueryVersion(client);
+}
+
+static
+int SProcGetReservedColormapEntries (client)
+ ClientPtr client;
+{
+ register int n;
+
+ REQUEST (xXcupGetReservedColormapEntriesReq);
+ swaps (&stuff->length, n);
+ swapl (&stuff->screen, n);
+ REQUEST_AT_LEAST_SIZE (xXcupGetReservedColormapEntriesReq);
+ return ProcGetReservedColormapEntries (client);
+}
+
+static
+int SProcStoreColors (client)
+ ClientPtr client;
+{
+ register int n;
+ int count;
+ xColorItem* pItem;
+
+ REQUEST (xXcupStoreColorsReq);
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xXcupStoreColorsReq);
+ swapl(&stuff->cmap, n);
+ pItem = (xColorItem*) &stuff[1];
+ for(count = LengthRestB(stuff)/sizeof(xColorItem); --count >= 0; )
+ SwapColorItem(pItem++);
+ return ProcStoreColors (client);
+}
+
+static
+int SProcDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XcupQueryVersion:
+ return SProcQueryVersion (client);
+ case X_XcupGetReservedColormapEntries:
+ return SProcGetReservedColormapEntries (client);
+ case X_XcupStoreColors:
+ return SProcStoreColors (client);
+ default:
+ return BadRequest;
+ }
+}
+
+
diff --git a/Xext/dpms.c b/Xext/dpms.c
new file mode 100644
index 000000000..ebc992dc2
--- /dev/null
+++ b/Xext/dpms.c
@@ -0,0 +1,433 @@
+/* $Xorg: dpms.c,v 1.3 2000/08/17 19:47:56 cpqbld Exp $ */
+/*****************************************************************
+
+Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "dpms.h"
+#include "dpmsstr.h"
+#include <stdio.h>
+
+static unsigned char DPMSCode;
+static int ProcDPMSDispatch(), SProcDPMSDispatch();
+static void DPMSResetProc();
+static int ProcDPMSGetVersion(), SProcDPMSGetVersion();
+static int ProcDPMSGetTimeouts(), SProcDPMSGetTimeouts();
+static int ProcDPMSSetTimeouts(), ProcDPMSSetTimeouts();
+static int ProcDPMSEnable(), ProcDPMSEnable();
+static int ProcDPMSDisable(), ProcDPMSDisable();
+static int ProcDPMSForceLevel(), ProcDPMSForceLevel();
+
+extern void Swap32Write(); /* XXX should be in header file */
+extern CARD32 ScreenSaverTime;
+extern CARD32 DPMSStandbyTime;
+extern CARD32 DPMSSuspendTime;
+extern CARD32 DPMSOffTime;
+extern BOOL DPMSCapableFlag;
+extern BOOL DPMSEnabled;
+extern CARD16 DPMSPowerLevel;
+
+void
+DPMSExtensionInit()
+{
+ ExtensionEntry *extEntry, *AddExtension();
+
+ if (extEntry = AddExtension(DPMSExtensionName, 0, 0,
+ ProcDPMSDispatch, SProcDPMSDispatch,
+ DPMSResetProc, StandardMinorOpcode))
+ DPMSCode = (unsigned char)extEntry->base;
+ return;
+}
+
+/*ARGSUSED*/
+static void
+DPMSResetProc (extEntry)
+ ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcDPMSGetVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSGetVersionReq);
+ xDPMSGetVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = DPMSMajorVersion;
+ rep.minorVersion = DPMSMinorVersion;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xDPMSGetVersionReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSCapable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSCapableReq);
+ xDPMSCapableReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xDPMSCapableReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.capable = DPMSCapableFlag;
+
+ WriteToClient(client, sizeof(xDPMSCapableReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSGetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSGetTimeoutsReq);
+ xDPMSGetTimeoutsReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.standby = DPMSStandbyTime / MILLI_PER_SECOND;
+ rep.suspend = DPMSSuspendTime / MILLI_PER_SECOND;
+ rep.off = DPMSOffTime / MILLI_PER_SECOND;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.standby, n);
+ swaps(&rep.suspend, n);
+ swaps(&rep.off, n);
+ }
+ WriteToClient(client, sizeof(xDPMSGetTimeoutsReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSSetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSSetTimeoutsReq);
+ register int n;
+
+ REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
+
+ if ((stuff->off != 0)&&(stuff->off < stuff->suspend))
+ {
+ client->errorValue = stuff->off;
+ return BadValue;
+ }
+ if ((stuff->suspend != 0)&&(stuff->suspend < stuff->standby))
+ {
+ client->errorValue = stuff->suspend;
+ return BadValue;
+ }
+
+ DPMSStandbyTime = stuff->standby * MILLI_PER_SECOND;
+ DPMSSuspendTime = stuff->suspend * MILLI_PER_SECOND;
+ DPMSOffTime = stuff->off * MILLI_PER_SECOND;
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSEnable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSEnableReq);
+
+ REQUEST_SIZE_MATCH(xDPMSEnableReq);
+
+ if (DPMSCapableFlag)
+ DPMSEnabled = TRUE;
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSDisable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSDisableReq);
+
+ REQUEST_SIZE_MATCH(xDPMSDisableReq);
+
+#ifdef DPMSExtension
+ DPMSSet(DPMSModeOn);
+#endif
+
+ DPMSEnabled = FALSE;
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSForceLevel(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSForceLevelReq);
+
+ REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
+
+ if (!DPMSEnabled)
+ return BadMatch;
+
+ if (stuff->level == DPMSModeOn) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis();
+ }
+#if 0
+ else if (stuff->level == DPMSModeStandby) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSStandbyTime;
+ } else if (stuff->level == DPMSModeSuspend) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSSuspendTime;
+ } else if (stuff->level == DPMSModeOff) {
+ lastDeviceEventTime.milliseconds =
+ GetTimeInMillis() - DPMSOffTime;
+ } else {
+ client->errorValue = stuff->level;
+ return BadValue;
+ }
+#endif
+
+#ifdef DPMSExtension
+ DPMSSet(stuff->level);
+#endif
+
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSInfo(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSInfoReq);
+ xDPMSInfoReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xDPMSInfoReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.power_level = DPMSPowerLevel;
+ rep.state = DPMSEnabled;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.power_level, n);
+ }
+ WriteToClient(client, sizeof(xDPMSInfoReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+static int
+ProcDPMSDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_DPMSGetVersion:
+ return ProcDPMSGetVersion(client);
+ case X_DPMSCapable:
+ return ProcDPMSCapable(client);
+ case X_DPMSGetTimeouts:
+ return ProcDPMSGetTimeouts(client);
+ case X_DPMSSetTimeouts:
+ return ProcDPMSSetTimeouts(client);
+ case X_DPMSEnable:
+ return ProcDPMSEnable(client);
+ case X_DPMSDisable:
+ return ProcDPMSDisable(client);
+ case X_DPMSForceLevel:
+ return ProcDPMSForceLevel(client);
+ case X_DPMSInfo:
+ return ProcDPMSInfo(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcDPMSGetVersion(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xDPMSGetVersionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSGetVersionReq);
+ swaps(&stuff->majorVersion, n);
+ swaps(&stuff->minorVersion, n);
+ return ProcDPMSGetVersion(client);
+}
+
+static int
+SProcDPMSCapable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSCapableReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSCapableReq);
+
+ return ProcDPMSCapable(client);
+}
+
+static int
+SProcDPMSGetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSGetTimeoutsReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSGetTimeoutsReq);
+
+ return ProcDPMSGetTimeouts(client);
+}
+
+static int
+SProcDPMSSetTimeouts(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSSetTimeoutsReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSSetTimeoutsReq);
+
+ swaps(&stuff->standby, n);
+ swaps(&stuff->suspend, n);
+ swaps(&stuff->off, n);
+ return ProcDPMSSetTimeouts(client);
+}
+
+static int
+SProcDPMSEnable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSEnableReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSEnableReq);
+
+ return ProcDPMSEnable(client);
+}
+
+static int
+SProcDPMSDisable(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSDisableReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSDisableReq);
+
+ return ProcDPMSDisable(client);
+}
+
+static int
+SProcDPMSForceLevel(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSForceLevelReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSForceLevelReq);
+
+ swaps(&stuff->level, n);
+
+ return ProcDPMSForceLevel(client);
+}
+
+static int
+SProcDPMSInfo(client)
+ register ClientPtr client;
+{
+ REQUEST(xDPMSInfoReq);
+ register int n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDPMSInfoReq);
+
+ return ProcDPMSInfo(client);
+}
+
+static int
+SProcDPMSDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_DPMSGetVersion:
+ return SProcDPMSGetVersion(client);
+ case X_DPMSCapable:
+ return SProcDPMSCapable(client);
+ case X_DPMSGetTimeouts:
+ return SProcDPMSGetTimeouts(client);
+ case X_DPMSSetTimeouts:
+ return SProcDPMSSetTimeouts(client);
+ case X_DPMSEnable:
+ return SProcDPMSEnable(client);
+ case X_DPMSDisable:
+ return SProcDPMSDisable(client);
+ case X_DPMSForceLevel:
+ return SProcDPMSForceLevel(client);
+ case X_DPMSInfo:
+ return SProcDPMSInfo(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/Xext/dpmsstubs.c b/Xext/dpmsstubs.c
new file mode 100644
index 000000000..6f635f42b
--- /dev/null
+++ b/Xext/dpmsstubs.c
@@ -0,0 +1,48 @@
+/* $Xorg: dpmsstubs.c,v 1.3 2000/08/17 19:47:56 cpqbld Exp $ */
+/*****************************************************************
+
+Copyright (c) 1996 Digital Equipment Corporation, Maynard, Massachusetts.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+
+******************************************************************/
+
+typedef int Bool;
+
+#define FALSE 0
+
+Bool DPMSSupported()
+{
+ return FALSE;
+}
+
+int DPSMGet(level)
+ int *level;
+{
+ return -1;
+}
+
+void DPMSSet(level)
+{
+
+}
diff --git a/Xext/mbuf.c b/Xext/mbuf.c
new file mode 100644
index 000000000..c65ed3dd2
--- /dev/null
+++ b/Xext/mbuf.c
@@ -0,0 +1,2041 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* $Xorg: mbuf.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#define _MULTIBUF_SERVER_ /* don't want Xlib structures */
+#include "multibufst.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "inputstr.h"
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+/* given an OtherClientPtr obj, get the ClientPtr */
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+/* given a MultibufferPtr b, get the ClientPtr */
+#define bClient(b) (clients[CLIENT_ID(b->pPixmap->drawable.id)])
+
+#define ValidEventMasks (ExposureMask|MultibufferClobberNotifyMask|MultibufferUpdateNotifyMask)
+
+#ifdef PANORAMIX
+extern int PanoramiXNumScreens;
+extern Bool noPanoramiXExtension;
+extern PanoramiXWindow *PanoramiXWinRoot;
+extern PanoramiXPmap *PanoramiXPmapRoot;
+extern PanoramiXData *panoramiXdataPtr;
+#endif
+
+/* The _Multibuffer and _Multibuffers structures below refer to each other,
+ * so we need this forward declaration
+ */
+
+typedef struct _Multibuffers *MultibuffersPtr;
+
+/*
+ * per-Multibuffer data
+ */
+
+typedef struct _Multibuffer {
+ MultibuffersPtr pMultibuffers; /* associated window data */
+ Mask eventMask; /* MultibufferClobberNotifyMask|ExposureMask|MultibufferUpdateNotifyMask */
+ Mask otherEventMask; /* mask of all other clients event masks */
+ OtherClients *otherClients; /* other clients that want events */
+ int number; /* index of this buffer into array */
+ int side; /* always Mono */
+ int clobber; /* Unclobbered, PartiallyClobbered, FullClobbered */
+ PixmapPtr pPixmap; /* associated pixmap */
+} MultibufferRec, *MultibufferPtr;
+
+/*
+ * per-window data
+ */
+
+typedef struct _Multibuffers {
+ WindowPtr pWindow; /* associated window */
+ int numMultibuffer; /* count of buffers */
+ int refcnt; /* ref count for delete */
+ int displayedMultibuffer; /* currently active buffer */
+ int updateAction; /* Undefined, Background, Untouched, Copied */
+ int updateHint; /* Frequent, Intermittent, Static */
+ int windowMode; /* always Mono */
+
+ TimeStamp lastUpdate; /* time of last update */
+
+ unsigned short width, height; /* last known window size */
+ short x, y; /* for static gravity */
+
+ MultibufferPtr buffers; /* array of numMultibuffer buffers */
+} MultibuffersRec;
+
+/*
+ * per-screen data
+ */
+typedef struct _MultibufferScreen {
+ Bool (*PositionWindow)();
+} MultibufferScreenRec, *MultibufferScreenPtr;
+
+/*
+ * per display-image-buffers request data.
+ */
+
+typedef struct _DisplayRequest {
+ struct _DisplayRequest *next;
+ TimeStamp activateTime;
+ ClientPtr pClient;
+ XID id;
+} DisplayRequestRec, *DisplayRequestPtr;
+
+static unsigned char MultibufferReqCode;
+static int MultibufferEventBase;
+static int MultibufferErrorBase;
+int MultibufferScreenIndex = -1;
+int MultibufferWindowIndex = -1;
+
+static void PerformDisplayRequest ();
+static void DisposeDisplayRequest ();
+static Bool QueueDisplayRequest ();
+
+static void BumpTimeStamp ();
+
+void MultibufferExpose ();
+void MultibufferUpdate ();
+static void AliasMultibuffer ();
+int CreateImageBuffers ();
+void DestroyImageBuffers ();
+int DisplayImageBuffers ();
+static void RecalculateMultibufferOtherEvents ();
+static int EventSelectForMultibuffer();
+
+
+/*
+ * The Pixmap associated with a buffer can be found as a resource
+ * with this type
+ */
+RESTYPE MultibufferDrawableResType;
+static int MultibufferDrawableDelete ();
+/*
+ * The per-buffer data can be found as a resource with this type.
+ * the resource id of the per-buffer data is the same as the resource
+ * id of the pixmap
+ */
+static RESTYPE MultibufferResType;
+static int MultibufferDelete ();
+/*
+ * The per-window data can be found as a resource with this type,
+ * using the window resource id
+ */
+static RESTYPE MultibuffersResType;
+static int MultibuffersDelete ();
+/*
+ * Clients other than the buffer creator attach event masks in
+ * OtherClient structures; each has a resource of this type.
+ */
+static RESTYPE OtherClientResType;
+static int OtherClientDelete ();
+
+/****************
+ * MultibufferExtensionInit
+ *
+ * Called from InitExtensions in main()
+ *
+ ****************/
+
+static int ProcMultibufferDispatch(), SProcMultibufferDispatch();
+static void MultibufferResetProc();
+static void SClobberNotifyEvent(), SUpdateNotifyEvent();
+static Bool MultibufferPositionWindow();
+
+void
+MultibufferExtensionInit()
+{
+ ExtensionEntry *extEntry;
+ int i, j;
+ ScreenPtr pScreen;
+ MultibufferScreenPtr pMultibufferScreen;
+
+ /*
+ * allocate private pointers in windows and screens. Allocating
+ * window privates may seem like an unnecessary expense, but every
+ * PositionWindow call must check to see if the window is
+ * multi-buffered; a resource lookup is too expensive.
+ */
+ MultibufferScreenIndex = AllocateScreenPrivateIndex ();
+ if (MultibufferScreenIndex < 0)
+ return;
+ MultibufferWindowIndex = AllocateWindowPrivateIndex ();
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ if (!AllocateWindowPrivate (pScreen, MultibufferWindowIndex, 0) ||
+ !(pMultibufferScreen = (MultibufferScreenPtr) xalloc (sizeof (MultibufferScreenRec))))
+ {
+ for (j = 0; j < i; j++)
+ xfree (screenInfo.screens[j]->devPrivates[MultibufferScreenIndex].ptr);
+ return;
+ }
+ pScreen->devPrivates[MultibufferScreenIndex].ptr = (pointer) pMultibufferScreen;
+ /*
+ * wrap PositionWindow to resize the pixmap when the window
+ * changes size
+ */
+ pMultibufferScreen->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = MultibufferPositionWindow;
+ }
+ /*
+ * create the resource types
+ */
+ MultibufferDrawableResType =
+ CreateNewResourceType(MultibufferDrawableDelete)|RC_CACHED|RC_DRAWABLE;
+ MultibufferResType = CreateNewResourceType(MultibufferDelete);
+ MultibuffersResType = CreateNewResourceType(MultibuffersDelete);
+ OtherClientResType = CreateNewResourceType(OtherClientDelete);
+ if (MultibufferDrawableResType && MultibufferResType &&
+ MultibuffersResType && OtherClientResType &&
+ (extEntry = AddExtension(MULTIBUFFER_PROTOCOL_NAME,
+ MultibufferNumberEvents,
+ MultibufferNumberErrors,
+ ProcMultibufferDispatch, SProcMultibufferDispatch,
+ MultibufferResetProc, StandardMinorOpcode)))
+ {
+ MultibufferReqCode = (unsigned char)extEntry->base;
+ MultibufferEventBase = extEntry->eventBase;
+ MultibufferErrorBase = extEntry->errorBase;
+ EventSwapVector[MultibufferEventBase + MultibufferClobberNotify] = SClobberNotifyEvent;
+ EventSwapVector[MultibufferEventBase + MultibufferUpdateNotify] = SUpdateNotifyEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+MultibufferResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+ ScreenPtr pScreen;
+ MultibufferScreenPtr pMultibufferScreen;
+
+ if (MultibufferScreenIndex < 0)
+ return;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ if (pScreen->devPrivates[MultibufferScreenIndex].ptr)
+ {
+ pMultibufferScreen = (MultibufferScreenPtr) pScreen->devPrivates[MultibufferScreenIndex].ptr;
+ pScreen->PositionWindow = pMultibufferScreen->PositionWindow;
+ xfree (pMultibufferScreen);
+ }
+ }
+}
+
+static int
+ProcGetBufferVersion (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufGetBufferVersionReq);
+ xMbufGetBufferVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xMbufGetBufferVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = MULTIBUFFER_MAJOR_VERSION;
+ rep.minorVersion = MULTIBUFFER_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof (xMbufGetBufferVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static void
+SetupBackgroundPainter (pWin, pGC)
+ WindowPtr pWin;
+ GCPtr pGC;
+{
+ pointer gcvalues[4];
+ int ts_x_origin, ts_y_origin;
+ PixUnion background;
+ int backgroundState;
+ Mask gcmask;
+
+ /*
+ * First take care of any ParentRelative stuff by altering the
+ * tile/stipple origin to match the coordinates of the upper-left
+ * corner of the first ancestor without a ParentRelative background.
+ * This coordinate is, of course, negative.
+ */
+
+ ts_x_origin = ts_y_origin = 0;
+ while (pWin->backgroundState == ParentRelative) {
+ ts_x_origin -= pWin->origin.x;
+ ts_y_origin -= pWin->origin.y;
+ pWin = pWin->parent;
+ }
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ switch (backgroundState)
+ {
+ case BackgroundPixel:
+ gcvalues[0] = (pointer) background.pixel;
+ gcvalues[1] = (pointer) FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ break;
+
+ case BackgroundPixmap:
+ gcvalues[0] = (pointer) FillTiled;
+ gcvalues[1] = (pointer) background.pixmap;
+ gcvalues[2] = (pointer) ts_x_origin;
+ gcvalues[3] = (pointer) ts_y_origin;
+ gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
+ break;
+
+ default:
+ gcvalues[0] = (pointer) GXnoop;
+ gcmask = GCFunction;
+ }
+ DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);
+}
+
+int
+CreateImageBuffers (pWin, nbuf, ids, action, hint)
+ WindowPtr pWin;
+ int nbuf;
+ XID *ids;
+ int action;
+ int hint;
+{
+ MultibuffersPtr pMultibuffers;
+ MultibufferPtr pMultibuffer;
+ ScreenPtr pScreen;
+ int width, height, depth;
+ int i;
+ GCPtr pClearGC = NULL;
+ xRectangle clearRect;
+
+ DestroyImageBuffers(pWin);
+ pMultibuffers = (MultibuffersPtr) xalloc (sizeof (MultibuffersRec) +
+ nbuf * sizeof (MultibufferRec));
+ if (!pMultibuffers)
+ return BadAlloc;
+ pMultibuffers->pWindow = pWin;
+ pMultibuffers->buffers = (MultibufferPtr) (pMultibuffers + 1);
+ pMultibuffers->refcnt = pMultibuffers->numMultibuffer = 0;
+ if (!AddResource (pWin->drawable.id, MultibuffersResType, (pointer) pMultibuffers))
+ return BadAlloc;
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+ depth = pWin->drawable.depth;
+ pScreen = pWin->drawable.pScreen;
+
+ if (pWin->backgroundState != None)
+ {
+ pClearGC = GetScratchGC (pWin->drawable.depth, pScreen);
+ SetupBackgroundPainter (pWin, pClearGC);
+ clearRect.x = clearRect.y = 0;
+ clearRect.width = width;
+ clearRect.height = height;
+ }
+
+ for (i = 0; i < nbuf; i++)
+ {
+ pMultibuffer = &pMultibuffers->buffers[i];
+ pMultibuffer->eventMask = 0L;
+ pMultibuffer->otherEventMask = 0L;
+ pMultibuffer->otherClients = (OtherClientsPtr) NULL;
+ pMultibuffer->number = i;
+ pMultibuffer->side = MultibufferSideMono;
+ pMultibuffer->clobber = MultibufferUnclobbered;
+ pMultibuffer->pMultibuffers = pMultibuffers;
+ if (!AddResource (ids[i], MultibufferResType, (pointer) pMultibuffer))
+ break;
+ pMultibuffer->pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, depth);
+ if (!pMultibuffer->pPixmap)
+ break;
+ if (!AddResource (ids[i], MultibufferDrawableResType, (pointer) pMultibuffer->pPixmap))
+ {
+ FreeResource (ids[i], MultibufferResType);
+ (*pScreen->DestroyPixmap) (pMultibuffer->pPixmap);
+ break;
+ }
+ pMultibuffer->pPixmap->drawable.id = ids[i];
+
+ if (i > 0 && pClearGC)
+ {
+ ValidateGC((DrawablePtr)pMultibuffer->pPixmap, pClearGC);
+ (*pClearGC->ops->PolyFillRect)((DrawablePtr)pMultibuffer->pPixmap,
+ pClearGC, 1, &clearRect);
+ }
+ }
+ pMultibuffers->numMultibuffer = i;
+ pMultibuffers->refcnt = i;
+ pMultibuffers->displayedMultibuffer = -1;
+ if (i > 0)
+ AliasMultibuffer (pMultibuffers, 0);
+ pMultibuffers->updateAction = action;
+ pMultibuffers->updateHint = hint;
+ pMultibuffers->windowMode = MultibufferModeMono;
+ pMultibuffers->lastUpdate.months = 0;
+ pMultibuffers->lastUpdate.milliseconds = 0;
+ pMultibuffers->width = width;
+ pMultibuffers->height = height;
+ pWin->devPrivates[MultibufferWindowIndex].ptr = (pointer) pMultibuffers;
+ if (pClearGC) FreeScratchGC(pClearGC);
+ return Success;
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXCreateImageBuffers (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufCreateImageBuffersReq);
+
+ register int result;
+ int i, j, k, len;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *next;
+ PanoramiXWindow *pPanoramiXids;
+ PanoramiXWindow *pPanoramiXPrev_ids;
+ PanoramiXPmap *local;
+ PanoramiXPmap *pPanoramiXPmap = PanoramiXPmapRoot;
+ CARD32 *value, *orig_ids;
+ XID *ids;
+ XID ID;
+ DrawablePtr pDrawable;
+
+ REQUEST_AT_LEAST_SIZE (xMbufCreateImageBuffersReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ len = stuff->length - (sizeof(xMbufCreateImageBuffersReq) >> 2);
+ ids = (XID *)ALLOCATE_LOCAL(sizeof(XID)*len);
+ orig_ids = (XID *)ALLOCATE_LOCAL(sizeof(XID)*len);
+ if (!ids)
+ return BadAlloc;
+ memcpy((char *)orig_ids, (char *) &stuff[1], len * sizeof(XID));
+ value = (CARD32 *)&stuff[1];
+ /* New resources are pixmaps */
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ for (i = 0; i < len; i++) {
+ ids[i] = (XID)orig_ids[i];
+ /* These will be MultibufferDrawableResType & MultibufferResType */
+ pPanoramiXPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXPmap, ids[i]);
+ if (!pPanoramiXPmap) {
+ local = (PanoramiXWindow *)Xcalloc(sizeof(PanoramiXWindow));
+ for (k = 0; k <= PanoramiXNumScreens - 1; k++) {
+ ID = k ? FakeClientID(client->index) : ids[i];
+ local->info[k].id = ID;
+ }
+ local->FreeMe = FALSE;
+ PANORAMIXFIND_LAST(pPanoramiXPmap, PanoramiXPmapRoot);
+ pPanoramiXPmap->next = local;
+ value[i] = local->info[j].id;
+ }else
+ value[i] = pPanoramiXPmap->info[j].id;
+ }
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = ProcCreateImageBuffers (client);
+ noPanoramiXExtension = FALSE;
+ BREAK_IF(result != Success);
+ }
+ if (result != Success) {
+ if (ids)
+ Xfree(ids);
+ if (orig_ids)
+ Xfree(orig_ids);
+ if (local)
+ Xfree(local);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcCreateImageBuffers (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufCreateImageBuffersReq);
+ xMbufCreateImageBuffersReply rep;
+ register int n;
+ WindowPtr pWin;
+ XID *ids;
+ int len, nbuf;
+ int i;
+ int err;
+
+ REQUEST_AT_LEAST_SIZE (xMbufCreateImageBuffersReq);
+ len = stuff->length - (sizeof(xMbufCreateImageBuffersReq) >> 2);
+ if (len == 0)
+ return BadLength;
+ if (!(pWin = LookupWindow (stuff->window, client)))
+ return BadWindow;
+ if (pWin->drawable.class == InputOnly)
+ return BadMatch;
+ switch (stuff->updateAction)
+ {
+ case MultibufferUpdateActionUndefined:
+ case MultibufferUpdateActionBackground:
+ case MultibufferUpdateActionUntouched:
+ case MultibufferUpdateActionCopied:
+ break;
+ default:
+ client->errorValue = stuff->updateAction;
+ return BadValue;
+ }
+ switch (stuff->updateHint)
+ {
+ case MultibufferUpdateHintFrequent:
+ case MultibufferUpdateHintIntermittent:
+ case MultibufferUpdateHintStatic:
+ break;
+ default:
+ client->errorValue = stuff->updateHint;
+ return BadValue;
+ }
+ nbuf = len;
+ ids = (XID *) &stuff[1];
+ for (i = 0; i < nbuf; i++)
+ {
+ LEGAL_NEW_RESOURCE(ids[i], client);
+ }
+ err = CreateImageBuffers (pWin, nbuf, ids,
+ stuff->updateAction, stuff->updateHint);
+ if (err != Success)
+ return err;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.numberBuffer = ((MultibuffersPtr) (pWin->devPrivates[MultibufferWindowIndex].ptr))->numMultibuffer;
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.numberBuffer, n);
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+#endif
+ WriteToClient(client, sizeof (xMbufCreateImageBuffersReply), (char*)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcDisplayImageBuffers (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufDisplayImageBuffersReq);
+ MultibufferPtr *pMultibuffer;
+ MultibuffersPtr *ppMultibuffers;
+ int nbuf;
+ XID *ids;
+ int i, j;
+ CARD32 minDelay;
+ TimeStamp activateTime, bufferTime;
+
+#ifdef PANORAMIX
+ WindowPtr pWndw;
+ PanoramiXPmap *pPanoramiXPmap = PanoramiXPmapRoot;
+ MultibufferPtr *pScrn0Multibuffer;
+ MultibuffersPtr *ppScrn0Multibuffers;
+ int k;
+ int panoramiX_buf = 0;
+ Bool FoundScreen;
+
+#endif
+
+ REQUEST_AT_LEAST_SIZE (xMbufDisplayImageBuffersReq);
+ nbuf = stuff->length - (sizeof (xMbufDisplayImageBuffersReq) >> 2);
+ if (!nbuf)
+ return Success;
+ minDelay = stuff->minDelay;
+ ids = (XID *) &stuff[1];
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ int maxbuf = 0;
+ maxbuf = nbuf * PanoramiXNumScreens;
+ ppScrn0Multibuffers = (MultibuffersPtr *) xalloc(maxbuf * sizeof (MultibuffersPtr));
+ pScrn0Multibuffer = (MultibufferPtr *) xalloc (maxbuf * sizeof(MultibufferPtr));
+ if (!ppScrn0Multibuffers || !pScrn0Multibuffer)
+ {
+ if ( sizeof (long) != sizeof(CARD32) ) DEALLOCATE_LOCAL(ids);
+ xfree (ppScrn0Multibuffers);
+ xfree (pScrn0Multibuffer);
+ client->errorValue = 0;
+ return BadAlloc;
+ }
+ }
+#endif
+ ppMultibuffers = (MultibuffersPtr *) ALLOCATE_LOCAL(nbuf * sizeof (MultibuffersPtr));
+ pMultibuffer = (MultibufferPtr *) ALLOCATE_LOCAL(nbuf * sizeof (MultibufferPtr));
+ if (!ppMultibuffers || !pMultibuffer)
+ {
+ if (ppMultibuffers) DEALLOCATE_LOCAL(ppMultibuffers);
+ if (pMultibuffer) DEALLOCATE_LOCAL(pMultibuffer);
+ client->errorValue = 0;
+ return BadAlloc;
+ }
+ activateTime.months = 0;
+ activateTime.milliseconds = 0;
+ for (i = 0; i < nbuf; i++)
+ {
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ pPanoramiXPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXPmap, ids[i]);
+ if (!pPanoramiXPmap){
+ if ( sizeof (long) != sizeof(CARD32) ) DEALLOCATE_LOCAL(ids);
+ xfree (ppMultibuffers);
+ xfree (pMultibuffer);
+ client->errorValue = ids[i];
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ }
+ FoundScreen = FALSE;
+ pScrn0Multibuffer[panoramiX_buf] = (MultibufferPtr)
+ LookupIDByType (ids[i], MultibufferResType);
+ ppScrn0Multibuffers[i] = pScrn0Multibuffer[i]->pMultibuffers;
+ pWndw = ppScrn0Multibuffers[i]->pWindow;
+ for (k = 0; (k < PanoramiXNumScreens && !FoundScreen); k++) {
+ pMultibuffer[panoramiX_buf] = (MultibufferPtr)
+ LookupIDByType (pPanoramiXPmap->info[k].id, MultibufferResType);
+ if (!pMultibuffer[i])
+ {
+ if ( sizeof (long) != sizeof(CARD32) ) DEALLOCATE_LOCAL(ids);
+ xfree (ppMultibuffers);
+ xfree (pMultibuffer);
+ client->errorValue = ids[i];
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ }
+ ppMultibuffers[panoramiX_buf] = pMultibuffer[panoramiX_buf]->pMultibuffers;
+ /* Figure out where the buffer resides, which screens */
+ if ( ((pWndw->drawable.x < 0) &&
+ (pWndw->drawable.x + pWndw->drawable.width < 0))
+ || ( (pWndw->drawable.x >
+ panoramiXdataPtr[k].x + panoramiXdataPtr[k].width) &&
+ (pWndw->drawable.x + pWndw->drawable.width >
+ panoramiXdataPtr[k].x + panoramiXdataPtr[k].width)))
+ /* its not on screen - k -, try next screen */
+ continue;
+ if ( ((pWndw->drawable.y < 0) &&
+ (pWndw->drawable.y + pWndw->drawable.height < 0))
+ || ( (pWndw->drawable.y >
+ panoramiXdataPtr[k].y + panoramiXdataPtr[k].height) &&
+ (pWndw->drawable.y + pWndw->drawable.height >
+ panoramiXdataPtr[k].y + panoramiXdataPtr[k].height)))
+ /* its not on screen - k -, try next screen */
+ continue;
+
+ /* The window resides on screen k, which means we need to
+ keep the buffer information for this screen */
+ panoramiX_buf++;
+
+ /* Is it only on this screen, or does it enter onto another
+ screen */
+ if ( ((pWndw->drawable.x + pWndw->drawable.width) <=
+ (panoramiXdataPtr[k].x + panoramiXdataPtr[k].width)) &&
+ ((pWndw->drawable.y + pWndw->drawable.height) <=
+ (panoramiXdataPtr[k].y +
+ panoramiXdataPtr[k].height )) )
+ FoundScreen = TRUE;
+ } /* for each screen k */
+ for (j = 0; j < i; j++)
+ {
+ if (ppScrn0Multibuffers[i] == ppScrn0Multibuffers[j])
+ {
+ if ( sizeof (long) != sizeof(CARD32) ) DEALLOCATE_LOCAL(ids);
+ DEALLOCATE_LOCAL(ppScrn0Multibuffers);
+ DEALLOCATE_LOCAL(pScrn0Multibuffer);
+ DEALLOCATE_LOCAL(ppMultibuffers);
+ DEALLOCATE_LOCAL(pMultibuffer);
+ client->errorValue = ids[i];
+ return BadMatch;
+ }
+ }
+ bufferTime = ppScrn0Multibuffers[i]->lastUpdate;
+ }else {
+#endif
+ pMultibuffer[i] = (MultibufferPtr) LookupIDByType (ids[i],
+MultibufferResType);
+ if (!pMultibuffer[i])
+ {
+ DEALLOCATE_LOCAL(ppMultibuffers);
+ DEALLOCATE_LOCAL(pMultibuffer);
+ client->errorValue = ids[i];
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ }
+ ppMultibuffers[i] = pMultibuffer[i]->pMultibuffers;
+ for (j = 0; j < i; j++)
+ {
+ if (ppMultibuffers[i] == ppMultibuffers[j])
+ {
+ DEALLOCATE_LOCAL(ppMultibuffers);
+ DEALLOCATE_LOCAL(pMultibuffer);
+ client->errorValue = ids[i];
+ return BadMatch;
+ }
+ }
+ bufferTime = ppMultibuffers[i]->lastUpdate;
+#ifdef PANORAMIX
+ }
+#endif
+ BumpTimeStamp (&bufferTime, minDelay);
+ if (CompareTimeStamps (bufferTime, activateTime) == LATER)
+ activateTime = bufferTime;
+ }
+ UpdateCurrentTime ();
+ if (CompareTimeStamps (activateTime, currentTime) == LATER &&
+ QueueDisplayRequest (client, activateTime))
+ {
+ ;
+ }
+ else
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension){
+ PerformDisplayRequest (ppMultibuffers, pMultibuffer, panoramiX_buf);
+ }else
+#endif
+ PerformDisplayRequest (ppMultibuffers, pMultibuffer, nbuf);
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension){
+ DEALLOCATE_LOCAL(ppScrn0Multibuffers);
+ DEALLOCATE_LOCAL(pScrn0Multibuffer);
+ }
+#endif
+
+ DEALLOCATE_LOCAL(ppMultibuffers);
+ DEALLOCATE_LOCAL(pMultibuffer);
+ return Success;
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXDestroyImageBuffers (client)
+ ClientPtr client;
+{
+ REQUEST (xMbufDestroyImageBuffersReq);
+ WindowPtr pWin;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_SIZE_MATCH (xMbufDestroyImageBuffersReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = ProcDestroyImageBuffers (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcDestroyImageBuffers (client)
+ register ClientPtr client;
+{
+ REQUEST (xMbufDestroyImageBuffersReq);
+ WindowPtr pWin;
+
+ REQUEST_SIZE_MATCH (xMbufDestroyImageBuffersReq);
+ if (!(pWin = LookupWindow (stuff->window, client)))
+ return BadWindow;
+ DestroyImageBuffers (pWin);
+ return Success;
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXSetMBufferAttributes (client)
+ ClientPtr client;
+{
+ REQUEST (xMbufSetMBufferAttributesReq);
+ WindowPtr pWin;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_SIZE_MATCH (xMbufSetMBufferAttributesReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = ProcSetMBufferAttributes (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcSetMBufferAttributes (client)
+ register ClientPtr client;
+{
+ REQUEST (xMbufSetMBufferAttributesReq);
+ WindowPtr pWin;
+ MultibuffersPtr pMultibuffers;
+ int len;
+ Mask vmask;
+ Mask index;
+ CARD32 updateHint;
+ XID *vlist;
+
+ REQUEST_AT_LEAST_SIZE (xMbufSetMBufferAttributesReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ pMultibuffers = (MultibuffersPtr)LookupIDByType (pWin->drawable.id, MultibuffersResType);
+ if (!pMultibuffers)
+ return BadMatch;
+ len = stuff->length - (sizeof (xMbufSetMBufferAttributesReq) >> 2);
+ vmask = stuff->valueMask;
+ if (len != Ones (vmask))
+ return BadLength;
+ vlist = (XID *) &stuff[1];
+ while (vmask)
+ {
+ index = (Mask) lowbit (vmask);
+ vmask &= ~index;
+ switch (index)
+ {
+ case MultibufferWindowUpdateHint:
+ updateHint = (CARD32) *vlist;
+ switch (updateHint)
+ {
+ case MultibufferUpdateHintFrequent:
+ case MultibufferUpdateHintIntermittent:
+ case MultibufferUpdateHintStatic:
+ pMultibuffers->updateHint = updateHint;
+ break;
+ default:
+ client->errorValue = updateHint;
+ return BadValue;
+ }
+ vlist++;
+ break;
+ default:
+ client->errorValue = stuff->valueMask;
+ return BadValue;
+ }
+ }
+ return Success;
+}
+
+static int
+ProcGetMBufferAttributes (client)
+ ClientPtr client;
+{
+ REQUEST (xMbufGetMBufferAttributesReq);
+ WindowPtr pWin;
+ MultibuffersPtr pMultibuffers;
+ XID *ids;
+ xMbufGetMBufferAttributesReply rep;
+ int i, n;
+
+ REQUEST_SIZE_MATCH (xMbufGetMBufferAttributesReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ pMultibuffers = (MultibuffersPtr)LookupIDByType (pWin->drawable.id, MultibuffersResType);
+ if (!pMultibuffers)
+ return BadAccess;
+ ids = (XID *) ALLOCATE_LOCAL (pMultibuffers->numMultibuffer * sizeof (XID));
+ if (!ids)
+ return BadAlloc;
+ for (i = 0; i < pMultibuffers->numMultibuffer; i++)
+ ids[i] = pMultibuffers->buffers[i].pPixmap->drawable.id;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = pMultibuffers->numMultibuffer;
+ rep.displayedBuffer = pMultibuffers->displayedMultibuffer;
+ rep.updateAction = pMultibuffers->updateAction;
+ rep.updateHint = pMultibuffers->updateHint;
+ rep.windowMode = pMultibuffers->windowMode;
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.displayedBuffer, n);
+ SwapLongs (ids, pMultibuffers->numMultibuffer);
+ }
+ WriteToClient (client, sizeof(xMbufGetMBufferAttributesReply),
+ (char *)&rep);
+ WriteToClient (client, (int)(pMultibuffers->numMultibuffer * sizeof (XID)),
+ (char *)ids);
+ DEALLOCATE_LOCAL((pointer) ids);
+ return client->noClientException;
+}
+
+static int
+ProcSetBufferAttributes (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufSetBufferAttributesReq);
+ MultibufferPtr pMultibuffer;
+ int len;
+ Mask vmask, index;
+ XID *vlist;
+ Mask eventMask;
+ int result;
+
+ REQUEST_AT_LEAST_SIZE (xMbufSetBufferAttributesReq);
+ pMultibuffer = (MultibufferPtr) LookupIDByType (stuff->buffer, MultibufferResType);
+ if (!pMultibuffer)
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ len = stuff->length - (sizeof (xMbufSetBufferAttributesReq) >> 2);
+ vmask = stuff->valueMask;
+ if (len != Ones (vmask))
+ return BadLength;
+ vlist = (XID *) &stuff[1];
+ while (vmask)
+ {
+ index = (Mask) lowbit (vmask);
+ vmask &= ~index;
+ switch (index)
+ {
+ case MultibufferBufferEventMask:
+ eventMask = (Mask) *vlist;
+ vlist++;
+ result = EventSelectForMultibuffer (pMultibuffer, client, eventMask);
+ if (result != Success)
+ return result;
+ break;
+ default:
+ client->errorValue = stuff->valueMask;
+ return BadValue;
+ }
+ }
+ return Success;
+}
+
+ProcGetBufferAttributes (client)
+ register ClientPtr client;
+{
+ REQUEST(xMbufGetBufferAttributesReq);
+ MultibufferPtr pMultibuffer;
+ xMbufGetBufferAttributesReply rep;
+ OtherClientsPtr other;
+ int n;
+
+ REQUEST_SIZE_MATCH (xMbufGetBufferAttributesReq);
+ pMultibuffer = (MultibufferPtr) LookupIDByType (stuff->buffer, MultibufferResType);
+ if (!pMultibuffer)
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.window = pMultibuffer->pMultibuffers->pWindow->drawable.id;
+ if (bClient (pMultibuffer) == client)
+ rep.eventMask = pMultibuffer->eventMask;
+ else
+ {
+ rep.eventMask = (Mask) 0L;
+ for (other = pMultibuffer->otherClients; other; other = other->next)
+ if (SameClient (other, client))
+ {
+ rep.eventMask = other->mask;
+ break;
+ }
+ }
+ rep.bufferIndex = pMultibuffer->number;
+ rep.side = pMultibuffer->side;
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.window, n);
+ swapl(&rep.eventMask, n);
+ swaps(&rep.bufferIndex, n);
+ }
+ WriteToClient(client, sizeof (xMbufGetBufferAttributesReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcGetBufferInfo (client)
+ register ClientPtr client;
+{
+ REQUEST (xMbufGetBufferInfoReq);
+ DrawablePtr pDrawable;
+ xMbufGetBufferInfoReply rep;
+ ScreenPtr pScreen;
+ int i, j, k;
+ int n;
+ xMbufBufferInfo *pInfo;
+ int nInfo;
+ DepthPtr pDepth;
+
+ pDrawable = (DrawablePtr) LookupDrawable (stuff->drawable, client);
+ if (!pDrawable)
+ return BadDrawable;
+ pScreen = pDrawable->pScreen;
+ nInfo = 0;
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ pDepth = &pScreen->allowedDepths[i];
+ nInfo += pDepth->numVids;
+ }
+ pInfo = (xMbufBufferInfo *)
+ ALLOCATE_LOCAL (nInfo * sizeof (xMbufBufferInfo));
+ if (!pInfo)
+ return BadAlloc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = nInfo * (sizeof (xMbufBufferInfo) >> 2);
+ rep.normalInfo = nInfo;
+ rep.stereoInfo = 0;
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.normalInfo, n);
+ swaps(&rep.stereoInfo, n);
+ }
+
+ k = 0;
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ pDepth = &pScreen->allowedDepths[i];
+ for (j = 0; j < pDepth->numVids; j++)
+ {
+ pInfo[k].visualID = pDepth->vids[j];
+ pInfo[k].maxBuffers = 0;
+ pInfo[k].depth = pDepth->depth;
+ if (client->swapped)
+ {
+ swapl (&pInfo[k].visualID, n);
+ swaps (&pInfo[k].maxBuffers, n);
+ }
+ k++;
+ }
+ }
+ WriteToClient (client, sizeof (xMbufGetBufferInfoReply), (pointer) &rep);
+ WriteToClient (client, (int) nInfo * sizeof (xMbufBufferInfo), (pointer) pInfo);
+ DEALLOCATE_LOCAL ((pointer) pInfo);
+ return client->noClientException;
+}
+
+static int
+ProcClearImageBufferArea (client)
+ register ClientPtr client;
+{
+ REQUEST (xMbufClearImageBufferAreaReq);
+ MultibufferPtr pMultibuffer;
+ WindowPtr pWin;
+ xRectangle clearRect;
+ int width, height;
+ DrawablePtr pDrawable;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH (xMbufClearImageBufferAreaReq);
+ pMultibuffer = (MultibufferPtr) LookupIDByType (stuff->buffer, MultibufferResType);
+ if (!pMultibuffer)
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ pWin = pMultibuffer->pMultibuffers->pWindow;
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+ pScreen = pWin->drawable.pScreen;
+
+ clearRect.x = stuff->x;
+ clearRect.y = stuff->y;
+ clearRect.width = stuff->width ? stuff->width : width;
+ clearRect.height = stuff->height ? stuff->height : height;
+
+ if (pWin->backgroundState != None)
+ {
+ GCPtr pClearGC;
+ pClearGC = GetScratchGC (pWin->drawable.depth, pScreen);
+ SetupBackgroundPainter (pWin, pClearGC);
+
+ if (pMultibuffer->number == pMultibuffer->pMultibuffers->displayedMultibuffer)
+ pDrawable = (DrawablePtr)pWin;
+ else
+ pDrawable = (DrawablePtr)pMultibuffer->pPixmap;
+
+ ValidateGC(pDrawable, pClearGC);
+ (*pClearGC->ops->PolyFillRect) (pDrawable, pClearGC, 1, &clearRect);
+ FreeScratchGC(pClearGC);
+ }
+
+ if (stuff->exposures)
+ {
+ RegionRec region;
+ BoxRec box;
+ box.x1 = clearRect.x;
+ box.y1 = clearRect.y;
+ box.x2 = clearRect.x + clearRect.width;
+ box.y2 = clearRect.y + clearRect.height;
+ REGION_INIT(pScreen, &region, &box, 1);
+ MultibufferExpose(pMultibuffer, &region);
+ REGION_UNINIT(pScreen, &region);
+ }
+ return Success;
+}
+
+static int
+ProcMultibufferDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_MbufGetBufferVersion:
+ return ProcGetBufferVersion (client);
+ case X_MbufCreateImageBuffers:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXCreateImageBuffers (client);
+ else
+ return ProcCreateImageBuffers (client);
+#else
+ return ProcCreateImageBuffers (client);
+#endif
+ case X_MbufDisplayImageBuffers:
+ return ProcDisplayImageBuffers (client);
+ case X_MbufDestroyImageBuffers:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXDestroyImageBuffers (client);
+ else
+ return ProcDestroyImageBuffers (client);
+#else
+ return ProcDestroyImageBuffers (client);
+#endif
+ case X_MbufSetMBufferAttributes:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXSetMBufferAttributes (client);
+ else
+ return ProcSetMBufferAttributes (client);
+#else
+ return ProcSetMBufferAttributes (client);
+#endif
+ case X_MbufGetMBufferAttributes:
+ return ProcGetMBufferAttributes (client);
+ case X_MbufSetBufferAttributes:
+ return ProcSetBufferAttributes (client);
+ case X_MbufGetBufferAttributes:
+ return ProcGetBufferAttributes (client);
+ case X_MbufGetBufferInfo:
+ return ProcGetBufferInfo (client);
+ case X_MbufClearImageBufferArea:
+ return ProcClearImageBufferArea (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcGetBufferVersion (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufGetBufferVersionReq);
+
+ swaps (&stuff->length, n);
+ return ProcGetBufferVersion (client);
+}
+
+static int
+SProcCreateImageBuffers (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufCreateImageBuffersReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xMbufCreateImageBuffersReq);
+ swapl (&stuff->window, n);
+ SwapRestL(stuff);
+ return ProcCreateImageBuffers (client);
+}
+
+static int
+SProcDisplayImageBuffers (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufDisplayImageBuffersReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xMbufDisplayImageBuffersReq);
+ swaps (&stuff->minDelay, n);
+ swaps (&stuff->maxDelay, n);
+ SwapRestL(stuff);
+ return ProcDisplayImageBuffers (client);
+}
+
+static int
+SProcDestroyImageBuffers (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufDestroyImageBuffersReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xMbufDestroyImageBuffersReq);
+ swapl (&stuff->window, n);
+ return ProcDestroyImageBuffers (client);
+}
+
+static int
+SProcSetMBufferAttributes (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufSetMBufferAttributesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xMbufSetMBufferAttributesReq);
+ swapl (&stuff->window, n);
+ swapl (&stuff->valueMask, n);
+ SwapRestL(stuff);
+ return ProcSetMBufferAttributes (client);
+}
+
+static int
+SProcGetMBufferAttributes (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufGetMBufferAttributesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xMbufGetMBufferAttributesReq);
+ swapl (&stuff->window, n);
+ return ProcGetMBufferAttributes (client);
+}
+
+static int
+SProcSetBufferAttributes (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufSetBufferAttributesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xMbufSetBufferAttributesReq);
+ swapl (&stuff->buffer, n);
+ swapl (&stuff->valueMask, n);
+ SwapRestL(stuff);
+ return ProcSetBufferAttributes (client);
+}
+
+static int
+SProcGetBufferAttributes (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufGetBufferAttributesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xMbufGetBufferAttributesReq);
+ swapl (&stuff->buffer, n);
+ return ProcGetBufferAttributes (client);
+}
+
+static int
+SProcGetBufferInfo (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xMbufGetBufferInfoReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xMbufGetBufferInfoReq);
+ swapl (&stuff->drawable, n);
+ return ProcGetBufferInfo (client);
+}
+
+static int
+SProcClearImageBufferArea(client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST(xMbufClearImageBufferAreaReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH (xMbufClearImageBufferAreaReq);
+ swapl(&stuff->buffer, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ return ProcClearImageBufferArea(client);
+}
+
+static int
+SProcMultibufferDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_MbufGetBufferVersion:
+ return SProcGetBufferVersion (client);
+ case X_MbufCreateImageBuffers:
+ return SProcCreateImageBuffers (client);
+ case X_MbufDisplayImageBuffers:
+ return SProcDisplayImageBuffers (client);
+ case X_MbufDestroyImageBuffers:
+ return SProcDestroyImageBuffers (client);
+ case X_MbufSetMBufferAttributes:
+ return SProcSetMBufferAttributes (client);
+ case X_MbufGetMBufferAttributes:
+ return SProcGetMBufferAttributes (client);
+ case X_MbufSetBufferAttributes:
+ return SProcSetBufferAttributes (client);
+ case X_MbufGetBufferAttributes:
+ return SProcGetBufferAttributes (client);
+ case X_MbufGetBufferInfo:
+ return SProcGetBufferInfo (client);
+ case X_MbufClearImageBufferArea:
+ return SProcClearImageBufferArea (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SUpdateNotifyEvent (from, to)
+ xMbufUpdateNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->buffer, to->buffer);
+ cpswapl (from->timeStamp, to->timeStamp);
+}
+
+static void
+SClobberNotifyEvent (from, to)
+ xMbufClobberNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->buffer, to->buffer);
+ to->state = from->state;
+}
+
+static void
+PerformDisplayRequest (ppMultibuffers, pMultibuffer, nbuf)
+ MultibufferPtr *pMultibuffer;
+ MultibuffersPtr *ppMultibuffers;
+ int nbuf;
+{
+ GCPtr pGC;
+ PixmapPtr pPrevPixmap, pNewPixmap;
+ xRectangle clearRect;
+ WindowPtr pWin;
+ RegionPtr pExposed;
+ int i;
+ MultibufferPtr pPrevMultibuffer;
+ XID graphicsExpose;
+
+ UpdateCurrentTime ();
+ for (i = 0; i < nbuf; i++)
+ {
+ pWin = ppMultibuffers[i]->pWindow;
+ pGC = GetScratchGC (pWin->drawable.depth, pWin->drawable.pScreen);
+ pPrevMultibuffer =
+ &ppMultibuffers[i]->buffers[ppMultibuffers[i]->displayedMultibuffer];
+ pPrevPixmap = pPrevMultibuffer->pPixmap;
+ pNewPixmap = pMultibuffer[i]->pPixmap;
+ switch (ppMultibuffers[i]->updateAction)
+ {
+ case MultibufferUpdateActionUndefined:
+ break;
+ case MultibufferUpdateActionBackground:
+ SetupBackgroundPainter (pWin, pGC);
+ ValidateGC ((DrawablePtr)pPrevPixmap, pGC);
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width = pPrevPixmap->drawable.width;
+ clearRect.height = pPrevPixmap->drawable.height;
+ (*pGC->ops->PolyFillRect) ((DrawablePtr)pPrevPixmap, pGC,
+ 1, &clearRect);
+ break;
+ case MultibufferUpdateActionUntouched:
+ /* copy the window to the pixmap that represents the
+ * currently displayed buffer
+ */
+ if (pPrevMultibuffer->eventMask & ExposureMask)
+ {
+ graphicsExpose = TRUE;
+ DoChangeGC (pGC, GCGraphicsExposures, &graphicsExpose, FALSE);
+ }
+ ValidateGC ((DrawablePtr)pPrevPixmap, pGC);
+ pExposed = (*pGC->ops->CopyArea)
+ ((DrawablePtr) pWin,
+ (DrawablePtr) pPrevPixmap,
+ pGC,
+ 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+
+ /* if we couldn't copy the whole window to the buffer,
+ * send expose events (if any client wants them)
+ */
+ if (pPrevMultibuffer->eventMask & ExposureMask)
+ { /* some client wants expose events */
+ if (pExposed)
+ {
+ RegionPtr pWinSize;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ extern RegionPtr CreateUnclippedWinSize();
+
+ pWinSize = CreateUnclippedWinSize (pWin);
+ /* pExposed is window-relative, but at this point
+ * pWinSize is screen-relative. Make pWinSize be
+ * window-relative so that region ops involving
+ * pExposed and pWinSize behave sensibly.
+ */
+ REGION_TRANSLATE(pScreen, pWinSize,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ REGION_INTERSECT(pScreen, pExposed, pExposed, pWinSize);
+ REGION_DESTROY(pScreen, pWinSize);
+ MultibufferExpose (pPrevMultibuffer, pExposed);
+ REGION_DESTROY(pScreen, pExposed);
+ }
+ graphicsExpose = FALSE;
+ DoChangeGC (pGC, GCGraphicsExposures, &graphicsExpose, FALSE);
+ }
+ break; /* end case MultibufferUpdateActionUntouched */
+
+ case MultibufferUpdateActionCopied:
+ ValidateGC ((DrawablePtr)pPrevPixmap, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr)pNewPixmap,
+ (DrawablePtr)pPrevPixmap, pGC,
+ 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+ break;
+ } /* end switch on update action */
+
+ /* display the new buffer */
+ ValidateGC ((DrawablePtr)pWin, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr)pNewPixmap, (DrawablePtr)pWin, pGC,
+ 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+ ppMultibuffers[i]->lastUpdate = currentTime;
+ MultibufferUpdate (pMultibuffer[i],
+ ppMultibuffers[i]->lastUpdate.milliseconds);
+ AliasMultibuffer (ppMultibuffers[i],
+ pMultibuffer[i] - ppMultibuffers[i]->buffers);
+ FreeScratchGC (pGC);
+ }
+}
+
+DrawablePtr
+GetBufferPointer (pWin, i)
+ WindowPtr pWin;
+ int i;
+{
+ MultibuffersPtr pMultibuffers;
+
+ if (!(pMultibuffers = (MultibuffersPtr) pWin->devPrivates[MultibufferWindowIndex].ptr))
+ return NULL;
+ return (DrawablePtr) pMultibuffers->buffers[i].pPixmap;
+}
+
+int
+DisplayImageBuffers (ids, nbuf)
+ XID *ids;
+ int nbuf;
+{
+ MultibufferPtr *pMultibuffer;
+ MultibuffersPtr *pMultibuffers;
+ int i, j;
+
+ pMultibuffer = (MultibufferPtr *) ALLOCATE_LOCAL (nbuf * sizeof *pMultibuffer +
+ nbuf * sizeof *pMultibuffers);
+ if (!pMultibuffer)
+ return BadAlloc;
+ pMultibuffers = (MultibuffersPtr *) (pMultibuffer + nbuf);
+ for (i = 0; i < nbuf; i++)
+ {
+ pMultibuffer[i] = (MultibufferPtr) LookupIDByType (ids[i], MultibufferResType);
+ if (!pMultibuffer[i])
+ {
+ DEALLOCATE_LOCAL (pMultibuffer);
+ return MultibufferErrorBase + MultibufferBadBuffer;
+ }
+ pMultibuffers[i] = pMultibuffer[i]->pMultibuffers;
+ for (j = 0; j < i; j++)
+ if (pMultibuffers[i] == pMultibuffers[j])
+ {
+ DEALLOCATE_LOCAL (pMultibuffer);
+ return BadMatch;
+ }
+ }
+ PerformDisplayRequest (pMultibuffers, pMultibuffer, nbuf);
+ DEALLOCATE_LOCAL (pMultibuffer);
+ return Success;
+}
+
+
+static Bool
+QueueDisplayRequest (client, activateTime)
+ ClientPtr client;
+ TimeStamp activateTime;
+{
+ /* see xtest.c:ProcXTestFakeInput for code similar to this */
+
+ if (!ClientSleepUntil(client, &activateTime, NULL, NULL))
+ {
+ return FALSE;
+ }
+ /* swap the request back so we can simply re-execute it */
+ if (client->swapped)
+ {
+ register int n;
+ REQUEST (xMbufDisplayImageBuffersReq);
+
+ SwapRestL(stuff);
+ swaps (&stuff->length, n);
+ swaps (&stuff->minDelay, n);
+ swaps (&stuff->maxDelay, n);
+ }
+ ResetCurrentRequest (client);
+ client->sequence--;
+ return TRUE;
+}
+
+
+/*
+ * Deliver events to a buffer
+ */
+
+static int
+DeliverEventsToMultibuffer (pMultibuffer, pEvents, count, filter)
+ MultibufferPtr pMultibuffer;
+ xEvent *pEvents;
+ int count;
+ Mask filter;
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ OtherClients *other;
+
+ /* if nobody wants the event, we're done */
+ if (!((pMultibuffer->otherEventMask|pMultibuffer->eventMask) & filter))
+ return 0;
+
+ /* maybe send event to owner */
+ if (attempt = TryClientEvents(
+ bClient(pMultibuffer), pEvents, count, pMultibuffer->eventMask, filter, (GrabPtr) 0))
+ {
+ if (attempt > 0)
+ deliveries++;
+ else
+ nondeliveries--;
+ }
+
+ /* maybe send event to other clients */
+ for (other = pMultibuffer->otherClients; other; other=other->next)
+ {
+ if (attempt = TryClientEvents(
+ rClient(other), pEvents, count, other->mask, filter, (GrabPtr) 0))
+ {
+ if (attempt > 0)
+ deliveries++;
+ else
+ nondeliveries--;
+ }
+ }
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/*
+ * Send Expose events to interested clients
+ */
+
+void
+MultibufferExpose (pMultibuffer, pRegion)
+ MultibufferPtr pMultibuffer;
+ RegionPtr pRegion;
+{
+ if (pRegion && !REGION_NIL(pRegion))
+ {
+ xEvent *pEvent;
+ PixmapPtr pPixmap;
+ register xEvent *pe;
+ register BoxPtr pBox;
+ register int i;
+ int numRects;
+
+ pPixmap = pMultibuffer->pPixmap;
+ REGION_TRANSLATE(pPixmap->drawable.pScreen, pRegion,
+ -pPixmap->drawable.x, -pPixmap->drawable.y);
+ /* XXX MultibufferExpose "knows" the region representation */
+ numRects = REGION_NUM_RECTS(pRegion);
+ pBox = REGION_RECTS(pRegion);
+
+ pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent));
+ if (pEvent) {
+ pe = pEvent;
+
+ for (i=1; i<=numRects; i++, pe++, pBox++)
+ {
+ pe->u.u.type = Expose;
+ pe->u.expose.window = pPixmap->drawable.id;
+ pe->u.expose.x = pBox->x1;
+ pe->u.expose.y = pBox->y1;
+ pe->u.expose.width = pBox->x2 - pBox->x1;
+ pe->u.expose.height = pBox->y2 - pBox->y1;
+ pe->u.expose.count = (numRects - i);
+ }
+ (void) DeliverEventsToMultibuffer (pMultibuffer, pEvent, numRects,
+ ExposureMask);
+ DEALLOCATE_LOCAL(pEvent);
+ }
+ }
+}
+
+/* send UpdateNotify event */
+void
+MultibufferUpdate (pMultibuffer, time)
+ MultibufferPtr pMultibuffer;
+ CARD32 time;
+{
+ xMbufUpdateNotifyEvent event;
+
+ event.type = MultibufferEventBase + MultibufferUpdateNotify;
+ event.buffer = pMultibuffer->pPixmap->drawable.id;
+ event.timeStamp = time;
+ (void) DeliverEventsToMultibuffer (pMultibuffer, (xEvent *)&event,
+ 1, (Mask)MultibufferUpdateNotifyMask);
+}
+
+/*
+ * The sample implementation will never generate MultibufferClobberNotify
+ * events
+ */
+
+void
+MultibufferClobber (pMultibuffer)
+ MultibufferPtr pMultibuffer;
+{
+ xMbufClobberNotifyEvent event;
+
+ event.type = MultibufferEventBase + MultibufferClobberNotify;
+ event.buffer = pMultibuffer->pPixmap->drawable.id;
+ event.state = pMultibuffer->clobber;
+ (void) DeliverEventsToMultibuffer (pMultibuffer, (xEvent *)&event,
+ 1, (Mask)MultibufferClobberNotifyMask);
+}
+
+/*
+ * make the resource id for buffer i refer to the window
+ * drawable instead of the pixmap;
+ */
+
+static void
+AliasMultibuffer (pMultibuffers, i)
+ MultibuffersPtr pMultibuffers;
+ int i;
+{
+ MultibufferPtr pMultibuffer;
+
+ if (i == pMultibuffers->displayedMultibuffer)
+ return;
+ /*
+ * remove the old association
+ */
+ if (pMultibuffers->displayedMultibuffer >= 0)
+ {
+ pMultibuffer = &pMultibuffers->buffers[pMultibuffers->displayedMultibuffer];
+ ChangeResourceValue (pMultibuffer->pPixmap->drawable.id,
+ MultibufferDrawableResType,
+ (pointer) pMultibuffer->pPixmap);
+ }
+ /*
+ * make the new association
+ */
+ pMultibuffer = &pMultibuffers->buffers[i];
+ ChangeResourceValue (pMultibuffer->pPixmap->drawable.id,
+ MultibufferDrawableResType,
+ (pointer) pMultibuffers->pWindow);
+ pMultibuffers->displayedMultibuffer = i;
+}
+
+/*
+ * free everything associated with multibuffering for this
+ * window
+ */
+
+void
+DestroyImageBuffers (pWin)
+ WindowPtr pWin;
+{
+ FreeResourceByType (pWin->drawable.id, MultibuffersResType, FALSE);
+ /* Zero out the window's pointer to the buffers so they won't be reused */
+ pWin->devPrivates[MultibufferWindowIndex].ptr = NULL;
+}
+
+/*
+ * resize the buffers when the window is resized
+ */
+
+static Bool
+MultibufferPositionWindow (pWin, x, y)
+ WindowPtr pWin;
+ int x, y;
+{
+ ScreenPtr pScreen;
+ MultibufferScreenPtr pMultibufferScreen;
+ MultibuffersPtr pMultibuffers;
+ MultibufferPtr pMultibuffer;
+ int width, height;
+ int i;
+ int dx, dy, dw, dh;
+ int sourcex, sourcey;
+ int destx, desty;
+ PixmapPtr pPixmap;
+ GCPtr pGC;
+ int savewidth, saveheight;
+ xRectangle clearRect;
+ Bool clear;
+
+ pScreen = pWin->drawable.pScreen;
+ pMultibufferScreen = (MultibufferScreenPtr) pScreen->devPrivates[MultibufferScreenIndex].ptr;
+ (*pMultibufferScreen->PositionWindow) (pWin, x, y);
+
+ /* if this window is not multibuffered, we're done */
+ if (!(pMultibuffers = (MultibuffersPtr) pWin->devPrivates[MultibufferWindowIndex].ptr))
+ return TRUE;
+
+ /* if new size is same as old, we're done */
+ if (pMultibuffers->width == pWin->drawable.width &&
+ pMultibuffers->height == pWin->drawable.height)
+ return TRUE;
+
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+ dx = pWin->drawable.x - pMultibuffers->x;
+ dy = pWin->drawable.x - pMultibuffers->y;
+ dw = width - pMultibuffers->width;
+ dh = height - pMultibuffers->height;
+ GravityTranslate (0, 0, -dx, -dy, dw, dh,
+ pWin->bitGravity, &destx, &desty);
+
+ /* if the window grew, remember to paint the window background,
+ * and maybe send expose events, for the new areas of the buffers
+ */
+ clear = pMultibuffers->width < width || pMultibuffers->height < height ||
+ pWin->bitGravity == ForgetGravity;
+
+ sourcex = 0;
+ sourcey = 0;
+ savewidth = pMultibuffers->width;
+ saveheight = pMultibuffers->height;
+ /* clip rectangle to source and destination */
+ if (destx < 0)
+ {
+ savewidth += destx;
+ sourcex -= destx;
+ destx = 0;
+ }
+ if (destx + savewidth > width)
+ savewidth = width - destx;
+ if (desty < 0)
+ {
+ saveheight += desty;
+ sourcey -= desty;
+ desty = 0;
+ }
+ if (desty + saveheight > height)
+ saveheight = height - desty;
+
+ pMultibuffers->width = width;
+ pMultibuffers->height = height;
+ pMultibuffers->x = pWin->drawable.x;
+ pMultibuffers->y = pWin->drawable.y;
+
+ pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+ if (clear)
+ {
+ SetupBackgroundPainter (pWin, pGC);
+ clearRect.x = 0;
+ clearRect.y = 0;
+ clearRect.width = width;
+ clearRect.height = height;
+ }
+ for (i = 0; i < pMultibuffers->numMultibuffer; i++)
+ {
+ pMultibuffer = &pMultibuffers->buffers[i];
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
+ pWin->drawable.depth);
+ if (!pPixmap)
+ {
+ DestroyImageBuffers (pWin);
+ break;
+ }
+ ValidateGC ((DrawablePtr)pPixmap, pGC);
+ /*
+ * I suppose this could avoid quite a bit of work if
+ * it computed the minimal area required.
+ */
+ if (clear)
+ (*pGC->ops->PolyFillRect) ((DrawablePtr)pPixmap, pGC, 1, &clearRect);
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ (*pGC->ops->CopyArea) ((DrawablePtr)pMultibuffer->pPixmap,
+ (DrawablePtr)pPixmap, pGC,
+ sourcex, sourcey, savewidth, saveheight,
+ destx, desty);
+ }
+ pPixmap->drawable.id = pMultibuffer->pPixmap->drawable.id;
+ (*pScreen->DestroyPixmap) (pMultibuffer->pPixmap);
+ pMultibuffer->pPixmap = pPixmap;
+ if (i != pMultibuffers->displayedMultibuffer)
+ {
+ ChangeResourceValue (pPixmap->drawable.id,
+ MultibufferDrawableResType,
+ (pointer) pPixmap);
+ }
+ }
+ FreeScratchGC (pGC);
+ return TRUE;
+}
+
+/* Resource delete func for MultibufferDrawableResType */
+/*ARGSUSED*/
+static int
+MultibufferDrawableDelete (value, id)
+ pointer value;
+ XID id;
+{
+ DrawablePtr pDrawable = (DrawablePtr)value;
+ WindowPtr pWin;
+ MultibuffersPtr pMultibuffers;
+ PixmapPtr pPixmap;
+
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ {
+ pWin = (WindowPtr) pDrawable;
+ pMultibuffers = (MultibuffersPtr) pWin->devPrivates[MultibufferWindowIndex].ptr;
+ pPixmap = pMultibuffers->buffers[pMultibuffers->displayedMultibuffer].pPixmap;
+ }
+ else
+ {
+ pPixmap = (PixmapPtr) pDrawable;
+ }
+ (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
+ return Success;
+}
+
+/* Resource delete func for MultibufferResType */
+/*ARGSUSED*/
+static int
+MultibufferDelete (value, id)
+ pointer value;
+ XID id;
+{
+ MultibufferPtr pMultibuffer = (MultibufferPtr)value;
+ MultibuffersPtr pMultibuffers;
+
+ pMultibuffers = pMultibuffer->pMultibuffers;
+ if (--pMultibuffers->refcnt == 0)
+ {
+ FreeResourceByType (pMultibuffers->pWindow->drawable.id,
+ MultibuffersResType, TRUE);
+ xfree (pMultibuffers);
+ }
+ return Success;
+}
+
+/* Resource delete func for MultibuffersResType */
+/*ARGSUSED*/
+static int
+MultibuffersDelete (value, id)
+ pointer value;
+ XID id;
+{
+ MultibuffersPtr pMultibuffers = (MultibuffersPtr)value;
+ int i;
+
+ if (pMultibuffers->refcnt == pMultibuffers->numMultibuffer)
+ {
+ for (i = pMultibuffers->numMultibuffer; --i >= 0; )
+ FreeResource (pMultibuffers->buffers[i].pPixmap->drawable.id, 0);
+ }
+ return Success;
+}
+
+/* Resource delete func for OtherClientResType */
+static int
+OtherClientDelete (value, id)
+ pointer value;
+ XID id;
+{
+ MultibufferPtr pMultibuffer = (MultibufferPtr)value;
+ register OtherClientsPtr other, prev;
+
+ prev = 0;
+ for (other = pMultibuffer->otherClients; other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ pMultibuffer->otherClients = other->next;
+ xfree (other);
+ RecalculateMultibufferOtherEvents (pMultibuffer);
+ break;
+ }
+ prev = other;
+ }
+ return Success;
+}
+
+static int
+EventSelectForMultibuffer (pMultibuffer, client, mask)
+ MultibufferPtr pMultibuffer;
+ ClientPtr client;
+ Mask mask;
+{
+ OtherClientsPtr other;
+
+ if (mask & ~ValidEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (bClient (pMultibuffer) == client)
+ {
+ pMultibuffer->eventMask = mask;
+ }
+ else /* some other client besides the creator wants events */
+ {
+ for (other = pMultibuffer->otherClients; other; other = other->next)
+ {
+ if (SameClient (other, client))
+ {
+ if (mask == 0)
+ {
+ FreeResource (other->resource, RT_NONE);
+ break;
+ }
+ other->mask = mask;
+ break;
+ }
+ }
+ if (!other)
+ { /* new client that never selected events on this buffer before */
+ other = (OtherClients *) xalloc (sizeof (OtherClients));
+ if (!other)
+ return BadAlloc;
+ other->mask = mask;
+ other->resource = FakeClientID (client->index);
+ if (!AddResource (other->resource, OtherClientResType, (pointer) pMultibuffer))
+ {
+ xfree (other);
+ return BadAlloc;
+ }
+ other->next = pMultibuffer->otherClients;
+ pMultibuffer->otherClients = other;
+ }
+ RecalculateMultibufferOtherEvents (pMultibuffer);
+ }
+ return (client->noClientException);
+}
+
+/* or together all the otherClients event masks */
+static void
+RecalculateMultibufferOtherEvents (pMultibuffer)
+ MultibufferPtr pMultibuffer;
+{
+ Mask otherEventMask;
+ OtherClients *other;
+
+ otherEventMask = 0L;
+ for (other = pMultibuffer->otherClients; other; other = other->next)
+ otherEventMask |= other->mask;
+ pMultibuffer->otherEventMask = otherEventMask;
+}
+
+/* add milliseconds to a timestamp, handling overflow */
+static void
+BumpTimeStamp (ts, inc)
+TimeStamp *ts;
+CARD32 inc;
+{
+ CARD32 newms;
+
+ newms = ts->milliseconds + inc;
+ if (newms < ts->milliseconds)
+ ts->months++;
+ ts->milliseconds = newms;
+}
diff --git a/Xext/mbufbf.c b/Xext/mbufbf.c
new file mode 100644
index 000000000..3c873086f
--- /dev/null
+++ b/Xext/mbufbf.c
@@ -0,0 +1,1052 @@
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+/* $Xorg: mbufbf.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "inputstr.h"
+#include "validate.h"
+#include <sys/time.h>
+
+#define _MULTIBUF_SERVER_ /* don't want Xlib structures */
+#define _MULTIBUF_BUFFER_
+#include "multibufst.h"
+
+/*
+Support for doublebuffer hardare
+
+This code is designed to support doublebuffer hardware where the
+displayed buffer is selected on a per-pixel basis by an additional bit
+plane, called the select plane. It could probably be easily modified
+to work with systems that use window-id planes.
+
+This is done by creating a new drawable type, DRAWABLE_BUFFER. The
+type has the same exact layout as a window drawable. Your code should
+treat a DRAWABLE_BUFFER the same as it would tread a DRAWABLE_WINDOW
+when handling the gc drawing functions. In addition, PaintWindowBackground,
+CopyWindow, and all of the gc drawing functions to be able to draw into both
+framebuffers. Which framebuffer to draw into is selected by the contents of
+ pWin->devPrivates[frameWindowPrivateIndex].
+The content of the devPrivate is either from frameBuffer[0] or
+frameBuffer[1], depending on which buffer is being drawn into. When
+ pWin->devPrivates[frameWindowPrivateIndex] == frameBuffer[0],
+the functions should draw into the front framebuffer. When
+ pWin->devPrivates[frameWindowPrivateIndex] == frameBuffer[1],
+the functions should draw into the back framebuffer.
+
+In addition, you need to provide a function that allows you to copy
+bits between the buffers (optional since CopyArea can be used) and a
+function that draws into the select plane. Then, you need to register
+your functions and other information, by calling:
+
+void
+RegisterDoubleBufferHardware(pScreen, nInfo, pInfo, frameBuffer, selectPlane,
+ CopyBufferBitsFunc, DrawSelectPlaneFunc)
+ int nInfo;
+ xMbufBufferInfo *pInfo;
+ DevUnion *frameBuffer;
+ DevUnion selectPlane;
+
+"pInfo" is an array indicating which visuals and depths that double
+buffering is supported on. "nInfo" is the length of the array.
+
+"frameBuffer" is array of length 2. The contents of the array element
+is ddx-specific. The content of frameBuffer[0] should, when placed in
+the window private, indicate that framebuffer 0 should be drawn into.
+The contents of frameBuffer[1], when placed into the window private,
+should indicate that framebuffer 1 should be drawn into.
+
+"selectPlane" is ddx-specific. It should contain information
+neccessary for your displayProc to access the select plane.
+It is passed to DrawSelectPlaneFunc.
+
+"CopyBufferBitsFunc" is a ddx-specific function that copies from one
+buffer of a multibuffered window to another buffer. If the CopyBufferBitsFunc
+is NULL, a default function will be used that calls pScreen->CopyArea.
+
+ void CopyBufferBitsFunc(pMBWindow, srcBufferNum, dstBufferNum)
+ mbufWindowPtr pMBWindow;
+ int srcBufferNum, dstBufferNum;
+
+"DrawSelectPlaneFunc" is a ddx-specific function that fills the
+regions "prgn" of select plane with the value "bufferNum". If
+selectPlane is a DrawablePtr (such as a PixmapPtr), you can pass
+NULL for DrawSelectPlaneFunc, a default function will be used that
+calls FillRectangle on the selectPlane.
+
+ void DrawSelectPlaneFunc(pScreen, selectPlane, prgn, bufferNum)
+ ScreenPtr pScreen;
+ DevUnion selectPlane;
+ RegionPtr prgn;
+ long bufferNum;
+
+...
+...
+...
+
+*/
+
+#define MAX_BUFFERS 2 /* Only supports 2 buffers */
+#define FRONT_BUFFER 0
+#define BACK_BUFFER 1
+
+
+/* Buffer drawables have the same structure as window drawables */
+typedef WindowRec BufferRec;
+typedef WindowPtr BufferPtr;
+
+
+/*
+ * Call RegisterHdwrBuffer for every screen that has doublebuffer hardware.
+ */
+
+static int bufNumInfo[MAXSCREENS];
+static xMbufBufferInfo *bufInfo[MAXSCREENS];
+static DevUnion *bufFrameBuffer[MAXSCREENS];
+static DevUnion bufselectPlane[MAXSCREENS];
+static void (* bufCopyBufferBitsFunc[MAXSCREENS])();
+static void (* bufDrawSelectPlaneFunc[MAXSCREENS])();
+
+static Bool bufMultibufferInit();
+
+
+void
+RegisterDoubleBufferHardware(pScreen, nInfo, pInfo, frameBuffer, selectPlane,
+ CopyBufferBitsFunc, DrawSelectPlaneFunc)
+ ScreenPtr pScreen;
+ int nInfo;
+ xMbufBufferInfo *pInfo;
+ DevUnion *frameBuffer;
+ DevUnion selectPlane;
+ void (* CopyBufferBitsFunc)();
+ void (* DrawSelectPlaneFunc)();
+{
+ bufNumInfo[pScreen->myNum] = nInfo;
+ bufInfo[pScreen->myNum] = pInfo;
+ bufFrameBuffer[pScreen->myNum] = frameBuffer;
+ bufselectPlane[pScreen->myNum] = selectPlane;
+
+ bufCopyBufferBitsFunc[pScreen->myNum] = CopyBufferBitsFunc;
+ bufDrawSelectPlaneFunc[pScreen->myNum] = DrawSelectPlaneFunc;
+
+ /* Register ourselves with device-independent multibuffers code */
+ RegisterMultibufferInit(pScreen, bufMultibufferInit);
+}
+
+
+/*
+ * Called by Multibuffer extension initialization.
+ * Initializes mbufScreenRec and its devPrivate.
+ */
+
+static Bool NoopDDA_True() { return TRUE; }
+static Bool bufPositionWindow();
+static int bufCreateImageBuffers();
+static void bufDestroyImageBuffers();
+static void bufDisplayImageBuffers();
+static void bufClearImageBufferArea();
+static void bufDestroyBuffer();
+static void bufCopyBufferBits();
+static void bufDrawSelectPlane();
+static void bufWrapScreenFuncs();
+static void bufResetProc();
+
+static void bufPostValidateTree();
+static void bufClipNotify();
+static void bufWindowExposures();
+static Bool bufChangeWindowAttributes();
+static void bufClearToBackground();
+static void bufCopyWindow();
+
+extern WindowPtr *WindowTable;
+
+static Bool
+bufMultibufferInit(pScreen, pMBScreen)
+ ScreenPtr pScreen;
+ mbufScreenPtr pMBScreen;
+{
+ mbufBufferPrivPtr pMBPriv;
+ BoxRec box;
+
+ /* Multibuffer info */
+ pMBScreen->nInfo = bufNumInfo[pScreen->myNum];
+ pMBScreen->pInfo = bufInfo[pScreen->myNum];
+
+ /* Hooks */
+ pMBScreen->CreateImageBuffers = bufCreateImageBuffers;
+ pMBScreen->DestroyImageBuffers = bufDestroyImageBuffers;
+ pMBScreen->DisplayImageBuffers = bufDisplayImageBuffers;
+ pMBScreen->ClearImageBufferArea = bufClearImageBufferArea;
+ pMBScreen->ChangeMBufferAttributes = NoopDDA_True;
+ pMBScreen->ChangeBufferAttributes = NoopDDA_True;
+ pMBScreen->DeleteBufferDrawable = bufDestroyBuffer;
+ pMBScreen->WrapScreenFuncs = bufWrapScreenFuncs;
+ pMBScreen->ResetProc = bufResetProc;
+ /* Create devPrivate part */
+ pMBPriv = (mbufBufferPrivPtr) xalloc(sizeof *pMBPriv);
+ if (!pMBPriv)
+ return (FALSE);
+
+ pMBScreen->devPrivate.ptr = (pointer) pMBPriv;
+ pMBPriv->frameBuffer = bufFrameBuffer[pScreen->myNum];
+ pMBPriv->selectPlane = bufselectPlane[pScreen->myNum];
+
+ /*
+ * Initializing the subtractRgn to the screen area will ensure that
+ * the selectPlane will get cleared on the first PostValidateTree.
+ */
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+
+ pMBPriv->rgnChanged = TRUE;
+ REGION_INIT(pScreen, &pMBPriv->backBuffer, &box, 1);
+ REGION_INIT(pScreen, &pMBPriv->subtractRgn, &box, 1);
+ REGION_INIT(pScreen, &pMBPriv->unionRgn, NullBox, 0);
+
+ /* Misc functions */
+ pMBPriv->CopyBufferBits = bufCopyBufferBitsFunc[pScreen->myNum];
+ pMBPriv->DrawSelectPlane = bufDrawSelectPlaneFunc[pScreen->myNum];
+
+ if (!pMBPriv->CopyBufferBits)
+ pMBPriv->CopyBufferBits = bufCopyBufferBits;
+
+ if (!pMBPriv->DrawSelectPlane)
+ pMBPriv->DrawSelectPlane = bufDrawSelectPlane;
+
+ /* screen functions */
+ pMBPriv->funcsWrapped = 0;
+ pMBPriv->inClearToBackground = FALSE;
+ pMBPriv->WindowExposures = NULL;
+ pMBPriv->CopyWindow = NULL;
+ pMBPriv->ClearToBackground = NULL;
+ pMBPriv->ClipNotify = NULL;
+ pMBPriv->ChangeWindowAttributes = NULL;
+
+ /* Start out wrapped to clear select plane */
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,PostValidateTree, bufPostValidateTree);
+ return TRUE;
+}
+
+static void
+UpdateBufferFromWindow(pBuffer, pWin)
+ BufferPtr pBuffer;
+ WindowPtr pWin;
+{
+ pBuffer->drawable.x = pWin->drawable.x;
+ pBuffer->drawable.y = pWin->drawable.y;
+ pBuffer->drawable.width = pWin->drawable.width;
+ pBuffer->drawable.height = pWin->drawable.height;
+
+ pBuffer->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ /* Update for PaintWindowBackground */
+ pBuffer->parent = pWin->parent;
+
+ /*
+ * Make the borderClip the same as the clipList so
+ * NotClippedByChildren comes out with just clipList.
+ */
+
+ pBuffer->clipList = pWin->clipList;
+ pBuffer->borderClip = pWin->clipList;
+ pBuffer->winSize = pWin->winSize;
+ pBuffer->borderSize = pWin->borderSize;
+
+ pBuffer->origin = pWin->origin;
+}
+
+static BufferPtr
+bufCreateBuffer(pScreen, pWin, bufferNum)
+ ScreenPtr pScreen;
+ WindowPtr pWin;
+ int bufferNum;
+{
+ mbufBufferPrivPtr pMBPriv;
+ DevUnion *devPrivates;
+ BufferPtr pBuffer;
+ int i;
+
+ pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ pBuffer = AllocateWindow(pWin->drawable.pScreen);
+ if (!pBuffer)
+ return (NULL);
+
+ /* XXX- Until we know what is needed, copy everything. */
+ devPrivates = pBuffer->devPrivates;
+ *pBuffer = *pWin;
+ pBuffer->devPrivates = devPrivates;
+
+ pBuffer->drawable.type = DRAWABLE_BUFFER;
+ pBuffer->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pBuffer->nextSib = NULL;
+ pBuffer->prevSib = NULL;
+ pBuffer->firstChild = NULL;
+ pBuffer->lastChild = NULL;
+
+ /* XXX - Worry about backingstore later */
+ pBuffer->backStorage = NULL;
+ pBuffer->backingStore = NotUseful;
+
+ /* XXX - Need to call pScreen->CreateWindow for tile/stipples
+ * or should I just copy the devPrivates?
+ */
+
+ for (i=0; i < pScreen->WindowPrivateLen; i++)
+ pBuffer->devPrivates[i] = pWin->devPrivates[i];
+
+ pBuffer->devPrivates[frameWindowPrivateIndex] =
+ pMBPriv->frameBuffer[bufferNum];
+
+ return pBuffer;
+}
+
+static void
+bufDestroyBuffer(pDrawable)
+ DrawablePtr pDrawable;
+{
+ xfree(pDrawable);
+}
+
+/*ARGSUSED*/
+static int
+bufCreateImageBuffers (pWin, nbuf, ids, action, hint)
+ WindowPtr pWin;
+ int nbuf;
+ XID *ids;
+ int action;
+ int hint;
+{
+ ScreenPtr pScreen;
+ mbufScreenPtr pMBScreen;
+ mbufWindowPtr pMBWindow;
+ mbufBufferPtr pMBBuffer;
+ int i;
+
+ pScreen = pWin->drawable.pScreen;
+ pMBScreen = MB_SCREEN_PRIV(pScreen);
+ pMBWindow = MB_WINDOW_PRIV(pWin);
+
+ pMBWindow->devPrivate.ptr = (pointer) REGION_CREATE(pScreen, 0,0);
+ if (!pMBWindow->devPrivate.ptr)
+ return(0);
+ REGION_COPY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr,
+ &pWin->clipList);
+
+ for (i = 0; i < nbuf; i++)
+ {
+ pMBBuffer = pMBWindow->buffers + i;
+ pMBBuffer->pDrawable = (DrawablePtr) bufCreateBuffer(pScreen,pWin,i);
+
+ if (!pMBBuffer->pDrawable)
+ break;
+
+ if (!AddResource (ids[i], MultibufferDrawableResType,
+ (pointer) pMBBuffer->pDrawable))
+ {
+ bufDestroyBuffer((BufferPtr) pMBBuffer->pDrawable);
+ break;
+ }
+ pMBBuffer->pDrawable->id = ids[i];
+
+ /*
+ * If window is already mapped, generate exposures and
+ * clear the area of the newly buffers.
+ */
+
+ if ((pWin->realized) && (i != pMBWindow->displayedMultibuffer))
+ (* pMBScreen->ClearImageBufferArea)(pMBBuffer, 0,0, 0,0, TRUE);
+ }
+
+ return i;
+}
+
+static void
+bufDestroyImageBuffers(pWin)
+ WindowPtr pWin;
+{
+ ScreenPtr pScreen;
+ mbufWindowPtr pMBWindow;
+
+ pScreen = pWin->drawable.pScreen;
+
+ if (pMBWindow = MB_WINDOW_PRIV(pWin))
+ {
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ /*
+ * if the backbuffer is currently being displayed, move the bits
+ * to the frontbuffer and display it instead.
+ */
+
+ if (pWin->realized && (pMBWindow->displayedMultibuffer == BACK_BUFFER))
+ {
+ (* pMBPriv->CopyBufferBits)(pMBWindow, BACK_BUFFER, FRONT_BUFFER);
+ REGION_SUBTRACT(pScreen, &pMBPriv->backBuffer,
+ &pMBPriv->backBuffer, &pWin->clipList);
+ (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
+ &pWin->clipList, FRONT_BUFFER);
+ }
+
+ /* Switch window rendering to front buffer */
+ pWin->devPrivates[frameWindowPrivateIndex] =
+ pMBPriv->frameBuffer[FRONT_BUFFER];
+
+ REGION_DESTROY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr);
+ pMBWindow->devPrivate.ptr = NULL;
+ }
+}
+
+/*
+ * Can be replaced by pScreen->ClearToBackground if pBuffer->eventMask
+ * and wOtherEventsMasks(pBuffer) were setup.
+ */
+
+static void
+bufClearImageBufferArea(pMBBuffer, x,y, w,h, generateExposures)
+ mbufBufferPtr pMBBuffer;
+ short x,y;
+ unsigned short w,h;
+ Bool generateExposures;
+{
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr pBSReg = NullRegion;
+ ScreenPtr pScreen;
+ BoxPtr extents;
+ int x1, y1, x2, y2;
+ BufferPtr pBuffer;
+
+ pBuffer = (BufferPtr) pMBBuffer->pDrawable;
+ /* compute everything using ints to avoid overflow */
+
+ x1 = pBuffer->drawable.x + x;
+ y1 = pBuffer->drawable.y + y;
+ if (w)
+ x2 = x1 + (int) w;
+ else
+ x2 = x1 + (int) pBuffer->drawable.width - (int) x;
+ if (h)
+ y2 = y1 + h;
+ else
+ y2 = y1 + (int) pBuffer->drawable.height - (int) y;
+
+ extents = &pBuffer->clipList.extents;
+
+ /* clip the resulting rectangle to the window clipList extents. This
+ * makes sure that the result will fit in a box, given that the
+ * screen is < 32768 on a side.
+ */
+
+ if (x1 < extents->x1)
+ x1 = extents->x1;
+ if (x2 > extents->x2)
+ x2 = extents->x2;
+ if (y1 < extents->y1)
+ y1 = extents->y1;
+ if (y2 > extents->y2)
+ y2 = extents->y2;
+
+ if (x2 <= x1 || y2 <= y1)
+ {
+ x2 = x1 = 0;
+ y2 = y1 = 0;
+ }
+
+ box.x1 = x1;
+ box.x2 = x2;
+ box.y1 = y1;
+ box.y2 = y2;
+
+ pScreen = pBuffer->drawable.pScreen;
+ REGION_INIT(pScreen, &reg, &box, 1);
+ if (pBuffer->backStorage)
+ {
+ /*
+ * If the window has backing-store on, call through the
+ * ClearToBackground vector to handle the special semantics
+ * (i.e. things backing store is to be cleared out and
+ * an Expose event is to be generated for those areas in backing
+ * store if generateExposures is TRUE).
+ */
+ pBSReg = (* pScreen->ClearBackingStore)(pBuffer, x, y, w, h,
+ generateExposures);
+ }
+
+ REGION_INTERSECT(pScreen, &reg, &reg, &pBuffer->clipList);
+ if (pBuffer->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pBuffer, &reg, PW_BACKGROUND);
+ if (generateExposures)
+ MultibufferExpose(pMBBuffer, &reg);
+#ifdef _notdef
+ /* XXBS - This is the original miClearToBackground code.
+ * WindowExposures needs to be called (or the functionality emulated)
+ * in order for backingStore to work, but first, pBuffer->eventMask
+ * and wOtherEventsMasks(pBuffer) need to be setup correctly.
+ */
+
+ if (generateExposures)
+ (*pScreen->WindowExposures)(pBuffer, &reg, pBSReg);
+ else if (pBuffer->backgroundState != None)
+ (*pScreen->PaintWindowBackground)(pBuffer, &reg, PW_BACKGROUND);
+#endif
+ REGION_UNINIT(pScreen, &reg);
+ if (pBSReg)
+ REGION_DESTROY(pScreen, pBSReg);
+}
+
+static void
+bufWrapScreenFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,PostValidateTree, bufPostValidateTree);
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClipNotify, bufClipNotify);
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,WindowExposures,bufWindowExposures);
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,ChangeWindowAttributes, bufChangeWindowAttributes);
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClearToBackground,bufClearToBackground);
+ WRAP_SCREEN_FUNC(pScreen,pMBPriv,CopyWindow,bufCopyWindow);
+}
+
+static void
+bufResetProc(pScreen)
+ ScreenPtr pScreen;
+{
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ /*
+ * frameBuffer, selectPlane, and pInfo should be freed by
+ * whoever called RegisterDoubleBufferHardware
+ */
+
+ REGION_UNINIT(pScreen, &pMBPriv->backBuffer);
+ REGION_UNINIT(pScreen, &pMBPriv->subtractRgn);
+ REGION_UNINIT(pScreen, &pMBPriv->unionRgn);
+ xfree(pMBPriv);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*
+ * Used if CopyBufferBitsFunc is not provided when registering.
+ * This should work for everybody since CopyArea needs to support
+ * copying between buffers anyway.
+ */
+
+static void
+bufCopyBufferBits(pMBWindow, srcBufferNum, dstBufferNum)
+ mbufWindowPtr pMBWindow;
+ int srcBufferNum, dstBufferNum;
+{
+ DrawablePtr pSrcBuffer, pDstBuffer;
+ GCPtr pGC;
+
+ pSrcBuffer = pMBWindow->buffers[srcBufferNum].pDrawable;
+ pDstBuffer = pMBWindow->buffers[dstBufferNum].pDrawable;
+
+ pGC = GetScratchGC (pDstBuffer->depth, pDstBuffer->pScreen);
+ if (!pGC)
+ return;
+
+ ValidateGC (pDstBuffer, pGC);
+ (* pGC->ops->CopyArea) (pSrcBuffer, pDstBuffer, pGC,
+ 0,0, pDstBuffer->width, pDstBuffer->height, 0,0);
+ FreeScratchGC (pGC);
+}
+
+/*
+ * Used if DrawSelectPlanFunc is not provided for when registering.
+ * However, it only works if selectPlane.ptr is a drawable. Also
+ * assumes that painting with color 0 selects the front buffer,
+ * while color 1 selects the back buffer.
+ */
+
+static void
+bufDrawSelectPlane(pScreen, selectPlane, prgn, bufferNum)
+ ScreenPtr pScreen;
+ DevUnion selectPlane;
+ RegionPtr prgn;
+ long bufferNum;
+{
+ DrawablePtr pDrawable;
+ GCPtr pGC;
+ register int i;
+ register BoxPtr pbox;
+ register xRectangle *prect;
+ int numRects;
+ XID value;
+
+ if (REGION_NUM_RECTS(prgn) == 0)
+ return;
+
+ pDrawable = (DrawablePtr) selectPlane.ptr;
+ pGC = GetScratchGC (pDrawable->depth, pScreen);
+ if (!pGC)
+ return;
+
+ prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) *
+ sizeof(xRectangle));
+ if (!prect)
+ {
+ FreeScratchGC(pGC);
+ return;
+ }
+
+ value = (XID) bufferNum;
+ DoChangeGC(pGC, GCForeground, &value, 0);
+ ValidateGC(pDrawable, pGC);
+
+ numRects = REGION_NUM_RECTS(prgn);
+ pbox = REGION_RECTS(prgn);
+ for (i= numRects; --i >= 0; pbox++, prect++)
+ {
+ prect->x = pbox->x1;
+ prect->y = pbox->y1;
+ prect->width = pbox->x2 - pbox->x1;
+ prect->height = pbox->y2 - pbox->y1;
+ }
+ prect -= numRects;
+ (* pGC->ops->PolyFillRect)(pDrawable, pGC, numRects, prect);
+
+ DEALLOCATE_LOCAL(prect);
+ FreeScratchGC (pGC);
+}
+
+
+static void
+bufDisplayImageBuffers(pScreen, ppMBWindow, ppMBBuffer, nbuf)
+ ScreenPtr pScreen;
+ mbufBufferPtr *ppMBBuffer;
+ mbufWindowPtr *ppMBWindow;
+ int nbuf;
+{
+ WindowPtr pWin;
+ BufferPtr pPrevBuffer, pNewBuffer;
+ int i, number;
+ mbufBufferPrivPtr pMBPriv;
+ mbufBufferPtr pPrevMBBuffer;
+
+ pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ for (i = 0; i < nbuf; i++)
+ {
+ number = ppMBBuffer[i]->number; /* 0=frontbuffer, 1=backbuffer */
+ pWin = ppMBWindow[i]->pWindow;
+ pPrevMBBuffer = MB_DISPLAYED_BUFFER(ppMBWindow[i]);
+
+ pPrevBuffer = (BufferPtr) pPrevMBBuffer->pDrawable;
+ pNewBuffer = (BufferPtr) ppMBBuffer[i]->pDrawable;
+
+ if (pPrevBuffer != pNewBuffer)
+ {
+ RegionPtr backBuffer = &pMBPriv->backBuffer;
+
+ /*
+ * Update the select plane and the backBuffer region.
+ */
+
+ (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
+ &pWin->clipList, number);
+
+ if (number == BACK_BUFFER)
+ REGION_UNION(pScreen, backBuffer, backBuffer,
+ &pWin->clipList);
+ else
+ REGION_SUBTRACT(pScreen, backBuffer, backBuffer,
+ &pWin->clipList);
+
+ /* Switch which framebuffer the window draws into */
+ pWin->devPrivates[frameWindowPrivateIndex] =
+ pMBPriv->frameBuffer[number];
+ }
+
+ switch (ppMBWindow[i]->updateAction)
+ {
+ case MultibufferUpdateActionUndefined:
+ break;
+ case MultibufferUpdateActionBackground:
+ (* MB_SCREEN_PRIV(pScreen)->ClearImageBufferArea)
+ (pPrevMBBuffer, 0,0, 0,0, FALSE);
+ break;
+ case MultibufferUpdateActionUntouched:
+ break;
+ case MultibufferUpdateActionCopied:
+ if (pPrevBuffer != pNewBuffer)
+ {
+ (* pMBPriv->CopyBufferBits) (ppMBWindow[i],
+ ppMBBuffer[i]->number, pPrevMBBuffer->number);
+ }
+ break;
+ }
+ }
+}
+
+/* Updates the backBuffer region and paints the selectPlane. */
+
+static void
+bufPostValidateTree(pParent, pChild, kind)
+ WindowPtr pParent, pChild;
+ VTKind kind;
+{
+ ScreenPtr pScreen;
+ mbufBufferPrivPtr pMBPriv;
+
+ if (pParent)
+ pScreen = pParent->drawable.pScreen;
+ else if (pChild)
+ pScreen = pChild->drawable.pScreen;
+ else
+ return; /* Hopeless */
+
+ pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, PostValidateTree);
+ if (pScreen->PostValidateTree)
+ (* pScreen->PostValidateTree)(pParent, pChild, kind);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, PostValidateTree);
+
+ /* Does backBuffer need to change? */
+ if (pMBPriv->rgnChanged)
+ {
+ RegionRec exposed;
+ RegionPtr pSubtractRgn, pUnionRgn;
+ Bool overlap;
+
+ pMBPriv->rgnChanged = FALSE;
+
+ pSubtractRgn = &pMBPriv->subtractRgn;
+ pUnionRgn = &pMBPriv->unionRgn;
+ REGION_VALIDATE(pScreen, pSubtractRgn, &overlap);
+#ifdef DEBUG
+ if (overlap)
+ FatalError("bufPostValidateTree: subtractRgn overlaps");
+#endif
+ REGION_VALIDATE(pScreen, pUnionRgn, &overlap);
+#ifdef DEBUG
+ if (overlap)
+ FatalError("bufPostValidateTree: unionRgn overlaps");
+#endif
+
+ /* Update backBuffer: subtract must come before union */
+ REGION_SUBTRACT(pScreen, &pMBPriv->backBuffer, &pMBPriv->backBuffer,
+ pSubtractRgn);
+ REGION_UNION(pScreen, &pMBPriv->backBuffer, &pMBPriv->backBuffer,
+ pUnionRgn);
+
+ /* Paint gained and lost backbuffer areas in select plane */
+ REGION_INIT(pScreen, &exposed, NullBox, 0);
+ REGION_SUBTRACT(pScreen, &exposed, pSubtractRgn, pUnionRgn);
+ (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
+ &exposed, FRONT_BUFFER);
+
+ REGION_SUBTRACT(pScreen, &exposed, pUnionRgn, pSubtractRgn);
+ (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane,
+ &exposed, BACK_BUFFER);
+
+ REGION_UNINIT(pScreen, &exposed);
+ REGION_EMPTY(pScreen, pSubtractRgn);
+ REGION_EMPTY(pScreen, pUnionRgn);
+ }
+}
+
+/* XXX - Knows region internals. */
+
+static Bool
+RegionsEqual(reg1, reg2)
+ RegionPtr reg1;
+ RegionPtr reg2;
+{
+ int i;
+ BoxPtr rects1, rects2;
+
+ if (reg1->extents.x1 != reg2->extents.x1) return FALSE;
+ if (reg1->extents.x2 != reg2->extents.x2) return FALSE;
+ if (reg1->extents.y1 != reg2->extents.y1) return FALSE;
+ if (reg1->extents.y2 != reg2->extents.y2) return FALSE;
+ if (REGION_NUM_RECTS(reg1) != REGION_NUM_RECTS(reg2)) return FALSE;
+
+ rects1 = REGION_RECTS(reg1);
+ rects2 = REGION_RECTS(reg2);
+ for (i = 0; i != REGION_NUM_RECTS(reg1); i++) {
+ if (rects1[i].x1 != rects2[i].x1) return FALSE;
+ if (rects1[i].x2 != rects2[i].x2) return FALSE;
+ if (rects1[i].y1 != rects2[i].y1) return FALSE;
+ if (rects1[i].y2 != rects2[i].y2) return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * If the window is multibuffered and displaying the backbuffer,
+ * add the old clipList to the subtractRgn and add the new clipList
+ * to the unionRgn. PostValidateTree will use subtractRgn and unionRgn
+ * to update the backBuffer region and the selectPlane.
+ *
+ * Copy changes to the window structure into the buffers.
+ * Send ClobberNotify events.
+ */
+
+static void
+bufClipNotify(pWin, dx,dy)
+ WindowPtr pWin;
+ int dx,dy;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+ mbufWindowPtr pMBWindow;
+ int i;
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClipNotify);
+ if (pScreen->ClipNotify)
+ (* pScreen->ClipNotify)(pWin, dx,dy);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClipNotify);
+
+ if (pMBWindow = MB_WINDOW_PRIV(pWin))
+ {
+ RegionPtr pOldClipList = (RegionPtr) pMBWindow->devPrivate.ptr;
+
+ if (! RegionsEqual(pOldClipList, &pWin->clipList))
+ {
+ if (pMBWindow->displayedMultibuffer == BACK_BUFFER)
+ {
+ pMBPriv->rgnChanged = TRUE;
+ REGION_APPEND(pScreen, &pMBPriv->subtractRgn, pOldClipList);
+ REGION_APPEND(pScreen, &pMBPriv->unionRgn, &pWin->clipList);
+ }
+
+ REGION_COPY(pScreen, pOldClipList,&pWin->clipList);
+ }
+
+ /* Update buffer x,y,w,h, and clipList */
+ for (i=0; i<pMBWindow->numMultibuffer; i++)
+ {
+ mbufBufferPtr pMBBuffer = pMBWindow->buffers + i;
+ if (pMBBuffer->clobber != pWin->visibility)
+ {
+ pMBBuffer->clobber = pWin->visibility;
+ MultibufferClobber(pMBBuffer);
+ }
+ UpdateBufferFromWindow(pMBBuffer->pDrawable, pWin);
+ }
+ }
+}
+
+/*
+ * Updates buffer's background fields when the window's changes.
+ * This is necessary because pScreen->PaintWindowBackground
+ * is used to paint the buffer.
+ *
+ * XXBS - Backingstore state will have be tracked too if it is supported.
+ */
+
+static Bool
+bufChangeWindowAttributes(pWin, mask)
+ WindowPtr pWin;
+ unsigned long mask;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+ mbufWindowPtr pMBWindow;
+ Bool ret;
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, ChangeWindowAttributes);
+ ret = (* pScreen->ChangeWindowAttributes)(pWin, mask);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, ChangeWindowAttributes);
+
+ if (pMBWindow = MB_WINDOW_PRIV(pWin))
+ {
+ if (mask & (CWBackPixmap | CWBackPixel))
+ {
+ BufferPtr pBuffer;
+ int i;
+
+ for (i=0; i<pMBWindow->displayedMultibuffer; i++)
+ {
+ pBuffer = (BufferPtr) pMBWindow->buffers[i].pDrawable;
+ pBuffer->backgroundState = pWin->backgroundState;
+ pBuffer->background = pWin->background;
+ }
+ }
+ }
+ return ret;
+}
+
+/*
+ * Send exposures and clear the background for a buffer whenever
+ * its corresponding window is exposed, except when called by
+ * ClearToBackground.
+ */
+
+static void
+bufWindowExposures(pWin, prgn, other_exposed)
+ WindowPtr pWin;
+ register RegionPtr prgn, other_exposed;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ mbufWindowPtr pMBWindow = MB_WINDOW_PRIV(pWin);
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+ RegionRec tmp_rgn;
+ int i;
+ Bool handleBuffers;
+
+ handleBuffers = (!pMBPriv->inClearToBackground) &&
+ (pWin->drawable.type == DRAWABLE_WINDOW) &&
+ pMBWindow && (prgn && !REGION_NIL(prgn));
+
+ /* miWindowExposures munges prgn and other_exposed. */
+ if (handleBuffers)
+ {
+ REGION_INIT(pScreen, &tmp_rgn, NullBox, 0);
+ REGION_COPY(pScreen, &tmp_rgn,prgn);
+ }
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, WindowExposures);
+ (* pScreen->WindowExposures) (pWin, prgn, other_exposed);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, WindowExposures);
+
+ if (!handleBuffers)
+ return;
+
+ /*
+ * Send expose events to all clients. Paint the exposed region for all
+ * buffers except the displayed buffer since it is handled when the
+ * window is painted.
+ *
+ * XXBS - Will have to be re-written to handle BackingStore on buffers.
+ */
+
+ for (i=0; i<pMBWindow->numMultibuffer; i++)
+ {
+ mbufBufferPtr pMBBuffer;
+ BufferPtr pBuffer;
+
+ pMBBuffer = pMBWindow->buffers + i;
+ pBuffer = (BufferPtr) pMBBuffer->pDrawable;
+
+ if (i != pMBWindow->displayedMultibuffer)
+ (* pScreen->PaintWindowBackground)(pBuffer,&tmp_rgn,PW_BACKGROUND);
+ if ((pMBBuffer->otherEventMask | pMBBuffer->eventMask) & ExposureMask)
+ MultibufferExpose(pMBBuffer, &tmp_rgn);
+ }
+
+ REGION_UNINIT(pScreen, &tmp_rgn);
+}
+
+/*
+ * Set ``inClearToBackground'' so that WindowExposures does not attempt
+ * to send expose events or clear the background on the buffers.
+ */
+
+static void
+bufClearToBackground(pWin, x,y,w,h, sendExpose)
+ WindowPtr pWin;
+ int x,y, w,h;
+ Bool sendExpose;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+
+ pMBPriv->inClearToBackground = TRUE;
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClearToBackground);
+ (* pScreen->ClearToBackground)(pWin, x,y,w,h, sendExpose);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, ClearToBackground);
+
+ pMBPriv->inClearToBackground = FALSE;
+}
+
+/*
+ * Move bits in both buffers. It does this by calling pScreen->CopyWindow
+ * twice, once with the root window's devPrivate[frameWindowPrivateIndex]
+ * pointing to the frontbuffer pixmap and once with it pointed to the
+ * backbuffer pixmap. It does this if there are *any* existing multibuffered
+ * window... a possible optimization is to copy the backbuffer only if this
+ * window or its inferiors are multibuffered. May be faster, maybe not.
+ *
+ * XXX - Only works if your CopyWindow checks the root window's devPrivate
+ * to see which buffer to draw into. Works for cfbPaintWindow.
+ */
+
+/*ARGSUSED*/
+static void
+bufCopyWindow(pWin, ptOldOrg, prgnSrc)
+ WindowPtr pWin;
+ DDXPointRec ptOldOrg;
+ RegionPtr prgnSrc;
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen);
+ WindowPtr pwinroot;
+ DevUnion save;
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, CopyWindow);
+
+ pwinroot = WindowTable[pScreen->myNum];
+ save = pwinroot->devPrivates[frameWindowPrivateIndex];
+
+ /*
+ * Copy front buffer
+ */
+
+ pwinroot->devPrivates[frameWindowPrivateIndex] =
+ pMBPriv->frameBuffer[FRONT_BUFFER];
+ (* pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ /*
+ * Copy back buffer
+ */
+
+ /* CopyWindow translates prgnSrc... translate it back for 2nd call. */
+ REGION_TRANSLATE(pScreen, prgnSrc,
+ ptOldOrg.x - pWin->drawable.x,
+ ptOldOrg.y - pWin->drawable.y);
+ pwinroot->devPrivates[frameWindowPrivateIndex] =
+ pMBPriv->frameBuffer[BACK_BUFFER];
+ (* pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ pwinroot->devPrivates[frameWindowPrivateIndex] = save;
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, void, CopyWindow);
+}
diff --git a/Xext/mbufpx.c b/Xext/mbufpx.c
new file mode 100644
index 000000000..9474cc9aa
--- /dev/null
+++ b/Xext/mbufpx.c
@@ -0,0 +1,646 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* $Xorg: mbufpx.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "inputstr.h"
+#include <sys/time.h>
+
+#define _MULTIBUF_SERVER_ /* don't want Xlib structures */
+#define _MULTIBUF_PIXMAP_
+#include "multibufst.h"
+
+
+static Bool NoopDDA_True() { return TRUE; }
+
+static Bool pixPositionWindow();
+static int pixCreateImageBuffers();
+static void pixDisplayImageBuffers();
+static void pixClearImageBufferArea();
+static void pixDeleteBufferDrawable();
+static void pixWrapScreenFuncs();
+static void pixResetProc();
+
+Bool
+pixMultibufferInit(pScreen, pMBScreen)
+ ScreenPtr pScreen;
+ mbufScreenPtr pMBScreen;
+{
+ int i, j, k;
+ xMbufBufferInfo *pInfo;
+ int nInfo;
+ DepthPtr pDepth;
+ mbufPixmapPrivPtr pMBPriv;
+
+ pMBScreen->CreateImageBuffers = pixCreateImageBuffers;
+ pMBScreen->DestroyImageBuffers = (void (*)())NoopDDA;
+ pMBScreen->DisplayImageBuffers = pixDisplayImageBuffers;
+ pMBScreen->ClearImageBufferArea = pixClearImageBufferArea;
+ pMBScreen->ChangeMBufferAttributes = NoopDDA_True;
+ pMBScreen->ChangeBufferAttributes = NoopDDA_True;
+ pMBScreen->DeleteBufferDrawable = pixDeleteBufferDrawable;
+ pMBScreen->WrapScreenFuncs = pixWrapScreenFuncs;
+ pMBScreen->ResetProc = pixResetProc;
+
+ /* Support every depth and visual combination that the screen does */
+
+ nInfo = 0;
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ pDepth = &pScreen->allowedDepths[i];
+ nInfo += pDepth->numVids;
+ }
+
+ pInfo = (xMbufBufferInfo *) xalloc (nInfo * sizeof (xMbufBufferInfo));
+ if (!pInfo)
+ return FALSE;
+
+ k = 0;
+ for (i = 0; i < pScreen->numDepths; i++)
+ {
+ pDepth = &pScreen->allowedDepths[i];
+ for (j = 0; j < pDepth->numVids; j++)
+ {
+ pInfo[k].visualID = pDepth->vids[j];
+ pInfo[k].maxBuffers = 0;
+ pInfo[k].depth = pDepth->depth;
+ k++;
+ }
+ }
+
+ pMBScreen->nInfo = nInfo;
+ pMBScreen->pInfo = pInfo;
+
+ /*
+ * Setup the devPrivate to mbufScreenRec
+ */
+
+ pMBPriv = (mbufPixmapPrivPtr) xalloc(sizeof(* pMBPriv));
+ if (!pMBPriv)
+ {
+ xfree(pInfo);
+ return (FALSE);
+ }
+ pMBScreen->devPrivate.ptr = (pointer) pMBPriv;
+ pMBPriv->PositionWindow = NULL;
+ pMBPriv->funcsWrapped = 0;
+
+ return TRUE;
+}
+
+/*ARGSUSED*/
+static int
+pixCreateImageBuffers (pWin, nbuf, ids, action, hint)
+ WindowPtr pWin;
+ int nbuf;
+ XID *ids;
+ int action;
+ int hint;
+{
+ mbufWindowPtr pMBWindow;
+ mbufBufferPtr pMBBuffer;
+ ScreenPtr pScreen;
+ int width, height, depth;
+ int i;
+
+ pMBWindow = MB_WINDOW_PRIV(pWin);
+
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+ depth = pWin->drawable.depth;
+ pScreen = pWin->drawable.pScreen;
+
+ for (i = 0; i < nbuf; i++)
+ {
+ pMBBuffer = &pMBWindow->buffers[i];
+ pMBBuffer->pDrawable = (DrawablePtr)
+ (*pScreen->CreatePixmap) (pScreen, width, height, depth);
+ if (!pMBBuffer->pDrawable)
+ break;
+
+ if (!AddResource (ids[i], MultibufferDrawableResType,
+ (pointer) pMBBuffer->pDrawable))
+ {
+ (*pScreen->DestroyPixmap) ((PixmapPtr) pMBBuffer->pDrawable);
+ break;
+ }
+ pMBBuffer->pDrawable->id = ids[i];
+
+ /*
+ * In the description of the CreateImageBuffers request:
+ * "If the window is mapped, or if these image buffers have
+ * backing store, their contents will be tiled with the window
+ * background, and zero or more expose events will be generated
+ * for each of these buffers."
+ */
+
+ (* MB_SCREEN_PRIV(pScreen)->ClearImageBufferArea)
+ (pMBBuffer, 0,0, 0,0, TRUE);
+ }
+
+ return i;
+}
+
+/*
+ * set up the gc to clear the pixmaps;
+ */
+static Bool
+SetupBackgroundPainter (pWin, pGC)
+ WindowPtr pWin;
+ GCPtr pGC;
+{
+ XID gcvalues[4];
+ int ts_x_origin, ts_y_origin;
+ PixUnion background;
+ int backgroundState;
+ Mask gcmask;
+
+ /*
+ * First take care of any ParentRelative stuff by altering the
+ * tile/stipple origin to match the coordinates of the upper-left
+ * corner of the first ancestor without a ParentRelative background.
+ * This coordinate is, of course, negative.
+ */
+
+ ts_x_origin = ts_y_origin = 0;
+ while (pWin->backgroundState == ParentRelative) {
+ ts_x_origin -= pWin->origin.x;
+ ts_y_origin -= pWin->origin.y;
+ pWin = pWin->parent;
+ }
+ backgroundState = pWin->backgroundState;
+ background = pWin->background;
+
+ switch (backgroundState)
+ {
+ case BackgroundPixel:
+ gcvalues[0] = (XID) background.pixel;
+ gcvalues[1] = FillSolid;
+ gcmask = GCForeground|GCFillStyle;
+ break;
+
+ case BackgroundPixmap:
+ gcvalues[0] = FillTiled;
+ gcvalues[1] = (XID) background.pixmap;
+ gcvalues[2] = ts_x_origin;
+ gcvalues[3] = ts_y_origin;
+ gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin;
+ break;
+
+ default:
+ return FALSE;
+ }
+ DoChangeGC(pGC, gcmask, gcvalues, TRUE);
+ return TRUE;
+}
+
+static void
+MultibufferPaintBackgroundRectangles(pWin, pDrawable, nrects, pRects)
+ WindowPtr pWin;
+ DrawablePtr pDrawable;
+ int nrects;
+ xRectangle *pRects;
+{
+ GCPtr pGC;
+
+ pGC = GetScratchGC (pWin->drawable.depth, pWin->drawable.pScreen);
+ if (SetupBackgroundPainter(pWin, pGC))
+ {
+ ValidateGC(pDrawable, pGC);
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrects, pRects);
+ }
+ FreeScratchGC(pGC);
+}
+
+static void
+MultibufferPaintBackgroundRegion(pWin, pDrawable, pRegion)
+ WindowPtr pWin;
+ DrawablePtr pDrawable;
+ RegionPtr pRegion;
+{
+ xRectangle *pRects;
+ int nrects = REGION_NUM_RECTS(pRegion);
+ BoxPtr pbox = REGION_RECTS(pRegion);
+
+ pRects = (xRectangle *)ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
+ if (pRects)
+ {
+ int i;
+ for (i = 0; i < nrects; i++)
+ {
+ pRects[i].x = pbox->x1;
+ pRects[i].y = pbox->y1;
+ pRects[i].width = pbox->x2 - pbox->x1;
+ pRects[i].height = pbox->y2 - pbox->y1;
+ }
+ MultibufferPaintBackgroundRectangles(pWin, pDrawable, nrects, pRects);
+ DEALLOCATE_LOCAL(pRects);
+ }
+}
+
+static void
+pixDisplayImageBuffers(pScreen, ppMBWindow, ppMBBuffer, nbuf)
+ mbufBufferPtr *ppMBBuffer;
+ mbufWindowPtr *ppMBWindow;
+ int nbuf;
+{
+ GCPtr pGC = NULL;
+ PixmapPtr pPrevPixmap, pNewPixmap;
+ WindowPtr pWin;
+ RegionPtr pExposed;
+ int i;
+ mbufBufferPtr pPrevMBBuffer;
+ XID bool;
+ xRectangle r;
+
+ UpdateCurrentTime ();
+ for (i = 0; i < nbuf; i++)
+ {
+ pWin = ppMBWindow[i]->pWindow;
+
+ /* Time to get a different scratch GC? */
+
+ if (!pGC
+ || pGC->depth != pWin->drawable.depth
+ || pGC->pScreen != pWin->drawable.pScreen)
+ {
+ if (pGC) FreeScratchGC(pGC);
+ pGC = GetScratchGC (pWin->drawable.depth, pWin->drawable.pScreen);
+ }
+ pPrevMBBuffer = MB_DISPLAYED_BUFFER(ppMBWindow[i]);
+ pPrevPixmap = (PixmapPtr) pPrevMBBuffer->pDrawable;
+ pNewPixmap = (PixmapPtr) ppMBBuffer[i]->pDrawable;
+
+ if (pPrevPixmap == pNewPixmap)
+ {
+ /* "If a specified buffer is already displayed, any delays and
+ * update action will still be performed for that buffer."
+ *
+ * We special-case this because applications do occasionally
+ * request a redundant DisplayImageBuffers, and we can save
+ * strokes by recognizing that the only update action that will
+ * change the buffer contents in this case is Background.
+ */
+ if (ppMBWindow[i]->updateAction == MultibufferUpdateActionBackground)
+ {
+ r.x = r.y = 0;
+ r.width = pWin->drawable.width;
+ r.height = pWin->drawable.height;
+ MultibufferPaintBackgroundRectangles(pWin, (DrawablePtr)pWin,
+ 1, &r);
+ }
+ }
+ else /* different buffer is being displayed */
+ {
+ /* perform update action */
+
+ switch (ppMBWindow[i]->updateAction)
+ {
+ case MultibufferUpdateActionUndefined:
+ break;
+
+ case MultibufferUpdateActionBackground:
+
+ r.x = r.y = 0;
+ r.width = pPrevPixmap->drawable.width;
+ r.height = pPrevPixmap->drawable.height;
+ MultibufferPaintBackgroundRectangles(pWin,
+ (DrawablePtr)pPrevPixmap,
+ 1, &r);
+ break;
+
+ case MultibufferUpdateActionUntouched:
+
+ /* copy the window to the pixmap that represents the
+ * currently displayed buffer
+ */
+
+ if (pPrevMBBuffer->eventMask & ExposureMask)
+ {
+ bool = TRUE;
+ DoChangeGC (pGC, GCGraphicsExposures, &bool, FALSE);
+ }
+ ValidateGC ((DrawablePtr)pPrevPixmap, pGC);
+ pExposed = (*pGC->ops->CopyArea)((DrawablePtr) pWin,
+ (DrawablePtr) pPrevPixmap,
+ pGC,
+ 0, 0,
+ pWin->drawable.width,
+ pWin->drawable.height,
+ 0, 0);
+
+ /* if we couldn't copy the whole window to the buffer,
+ * send expose events (if any client wants them)
+ */
+
+ if (pPrevMBBuffer->eventMask & ExposureMask)
+ { /* some client wants expose events */
+ if (pExposed)
+ {
+ RegionPtr pWinSize;
+ extern RegionPtr CreateUnclippedWinSize();
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ pWinSize = CreateUnclippedWinSize (pWin);
+ /*
+ * pExposed is window-relative, but at this point
+ * pWinSize is screen-relative. Make pWinSize be
+ * window-relative so that region ops involving
+ * pExposed and pWinSize behave sensibly.
+ */
+ REGION_TRANSLATE(pScreen, pWinSize,
+ -pWin->drawable.x,
+ -pWin->drawable.y);
+ REGION_INTERSECT(pScreen, pExposed, pExposed, pWinSize);
+ REGION_DESTROY(pScreen, pWinSize);
+ MultibufferExpose (pPrevMBBuffer, pExposed);
+ REGION_DESTROY(pScreen, pExposed);
+ }
+ bool = FALSE;
+ DoChangeGC (pGC, GCGraphicsExposures, &bool, FALSE);
+ } /* end some client wants expose events */
+
+ break; /* end case MultibufferUpdateActionUntouched */
+
+ case MultibufferUpdateActionCopied:
+
+ ValidateGC ((DrawablePtr)pPrevPixmap, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr)pNewPixmap,
+ (DrawablePtr)pPrevPixmap, pGC,
+ 0, 0, pWin->drawable.width,
+ pWin->drawable.height, 0, 0);
+ break;
+
+ } /* end switch on update action */
+
+ /* display the new buffer */
+
+ ValidateGC ((DrawablePtr)pWin, pGC);
+ (*pGC->ops->CopyArea) ((DrawablePtr)pNewPixmap, (DrawablePtr)pWin,
+ pGC, 0, 0,
+ pWin->drawable.width, pWin->drawable.height,
+ 0, 0);
+ }
+
+ ppMBWindow[i]->lastUpdate = currentTime;
+ }
+
+ if (pGC) FreeScratchGC (pGC);
+ return;
+}
+
+/*
+ * resize the buffers when the window is resized
+ */
+
+static Bool
+pixPositionWindow (pWin, x, y)
+ WindowPtr pWin;
+ int x, y;
+{
+ ScreenPtr pScreen;
+ mbufPixmapPrivPtr pMBPriv;
+ mbufWindowPtr pMBWindow;
+ mbufBufferPtr pMBBuffer;
+ int width, height;
+ int i;
+ int dx, dy, dw, dh;
+ int sourcex, sourcey;
+ int destx, desty;
+ PixmapPtr pPixmap;
+ GCPtr pGC;
+ int savewidth, saveheight;
+ Bool clear;
+ RegionRec exposedRegion;
+ Bool ret;
+
+ pScreen = pWin->drawable.pScreen;
+ pMBPriv = MB_SCREEN_PRIV_PIXMAP(pScreen);
+
+ UNWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, PositionWindow);
+ ret = (* pScreen->PositionWindow) (pWin, x, y);
+ REWRAP_SCREEN_FUNC(pScreen, pMBPriv, Bool, PositionWindow);
+
+ if (!(pMBWindow = MB_WINDOW_PRIV(pWin)))
+ return ret;
+
+ /* if new size is same as old, we're done */
+
+ if (pMBWindow->width == pWin->drawable.width &&
+ pMBWindow->height == pWin->drawable.height)
+ return ret;
+
+ width = pWin->drawable.width;
+ height = pWin->drawable.height;
+ dx = pWin->drawable.x - pMBWindow->x;
+ dy = pWin->drawable.x - pMBWindow->y;
+ dw = width - pMBWindow->width;
+ dh = height - pMBWindow->height;
+ GravityTranslate (0, 0, -dx, -dy, dw, dh,
+ pWin->bitGravity, &destx, &desty);
+
+ /* if the window grew, remember to paint the window background,
+ * and maybe send expose events, for the new areas of the buffers
+ */
+
+ clear = pMBWindow->width < width || pMBWindow->height < height ||
+ pWin->bitGravity == ForgetGravity;
+
+ sourcex = 0;
+ sourcey = 0;
+ savewidth = pMBWindow->width;
+ saveheight = pMBWindow->height;
+ /* clip rectangle to source and destination */
+ if (destx < 0)
+ {
+ savewidth += destx;
+ sourcex -= destx;
+ destx = 0;
+ }
+ if (destx + savewidth > width)
+ savewidth = width - destx;
+ if (desty < 0)
+ {
+ saveheight += desty;
+ sourcey -= desty;
+ desty = 0;
+ }
+ if (desty + saveheight > height)
+ saveheight = height - desty;
+
+ pMBWindow->width = width;
+ pMBWindow->height = height;
+ pMBWindow->x = pWin->drawable.x;
+ pMBWindow->y = pWin->drawable.y;
+
+ if (clear)
+ {
+ BoxRec box;
+
+ box.x1 = box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+ REGION_INIT(pScreen, &exposedRegion, &box, 1);
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ RegionRec preservedRegion;
+ box.x1 = destx;
+ box.y1 = desty;
+ box.x2 = destx + savewidth;
+ box.y2 = desty + saveheight;
+ REGION_INIT(pScreen, &preservedRegion, &box, 1);
+ REGION_SUBTRACT(pScreen, &exposedRegion, &exposedRegion, &preservedRegion);
+ REGION_UNINIT(pScreen, &preservedRegion);
+ }
+
+ } /* end if (clear) */
+
+ pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ /* create buffers with new window size */
+
+ for (i = 0; i < pMBWindow->numMultibuffer; i++)
+ {
+ pMBBuffer = &pMBWindow->buffers[i];
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, pWin->drawable.depth);
+ if (!pPixmap)
+ {
+ (* MB_SCREEN_PRIV(pScreen)->DestroyImageBuffers)(pWin);
+ break;
+ }
+ if (clear)
+ {
+ MultibufferPaintBackgroundRegion(pWin, (DrawablePtr)pPixmap, &exposedRegion);
+ MultibufferExpose(pMBBuffer, &exposedRegion);
+ }
+ if (pWin->bitGravity != ForgetGravity)
+ {
+ ValidateGC ((DrawablePtr)pPixmap, pGC);
+ (*pGC->ops->CopyArea) (pMBBuffer->pDrawable, (DrawablePtr)pPixmap,
+ pGC,
+ sourcex, sourcey, savewidth, saveheight,
+ destx, desty);
+ }
+ pPixmap->drawable.id = pMBBuffer->pDrawable->id;
+ (*pScreen->DestroyPixmap) ((PixmapPtr) pMBBuffer->pDrawable);
+ pMBBuffer->pDrawable = (DrawablePtr) pPixmap;
+ if (i != pMBWindow->displayedMultibuffer)
+ {
+ ChangeResourceValue (pPixmap->drawable.id,
+ MultibufferDrawableResType,
+ (pointer) pPixmap);
+ }
+ }
+ FreeScratchGC (pGC);
+ if (clear)
+ REGION_UNINIT(pScreen, &exposedRegion);
+ return TRUE;
+}
+
+static void
+pixWrapScreenFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ mbufPixmapPrivPtr pMBPriv = MB_SCREEN_PRIV_PIXMAP(pScreen);
+ WRAP_SCREEN_FUNC(pScreen, pMBPriv, PositionWindow, pixPositionWindow);
+}
+
+static void
+pixResetProc(pScreen)
+ ScreenPtr pScreen;
+{
+ mbufScreenPtr pMBScreen = MB_SCREEN_PRIV(pScreen);
+ mbufPixmapPrivPtr pMBPriv = MB_SCREEN_PRIV_PIXMAP(pScreen);
+
+ xfree(pMBScreen->pInfo);
+ xfree(pMBPriv);
+}
+
+static void
+pixClearImageBufferArea(pMBBuffer, x,y, width,height, exposures)
+ mbufBufferPtr pMBBuffer;
+ short x, y;
+ unsigned short width, height;
+ Bool exposures;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ BoxRec box;
+ RegionRec region;
+ int w_width, w_height;
+ DrawablePtr pDrawable;
+
+ pWin = pMBBuffer->pMBWindow->pWindow;
+ pScreen = pWin->drawable.pScreen;
+
+ w_width = pWin->drawable.width;
+ w_height = pWin->drawable.height;
+
+ box.x1 = x;
+ box.y1 = y;
+ box.x2 = width ? (box.x1 + width) : w_width;
+ box.y2 = height ? (box.y1 + height) : w_height;
+
+ if (box.x1 < 0) box.x1 = 0;
+ if (box.y1 < 0) box.y1 = 0;
+ if (box.x2 > w_width) box.x2 = w_width;
+ if (box.y2 > w_height) box.y2 = w_height;
+
+ REGION_INIT(pScreen, &region, &box, 1);
+
+ if (pMBBuffer->number == pMBBuffer->pMBWindow->displayedMultibuffer)
+ pDrawable = (DrawablePtr) pWin;
+ else
+ pDrawable = pMBBuffer->pDrawable;
+
+ MultibufferPaintBackgroundRegion(pWin, pDrawable, &region);
+
+ if (exposures)
+ MultibufferExpose(pMBBuffer, &region);
+
+ REGION_UNINIT(pScreen, &region);
+}
+
+static void
+pixDeleteBufferDrawable(pDrawable)
+ DrawablePtr pDrawable;
+{
+ (* pDrawable->pScreen->DestroyPixmap)((PixmapPtr) pDrawable);
+}
diff --git a/Xext/mitmisc.c b/Xext/mitmisc.c
new file mode 100644
index 000000000..63e496209
--- /dev/null
+++ b/Xext/mitmisc.c
@@ -0,0 +1,153 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* RANDOM CRUFT! THIS HAS NO OFFICIAL X CONSORTIUM OR X PROJECT TEAM BLESSING */
+
+/* $Xorg: mitmisc.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#define _MITMISC_SERVER_
+#include "mitmiscstr.h"
+
+extern Bool permitOldBugs;
+
+static unsigned char MITReqCode;
+static int ProcMITDispatch(), SProcMITDispatch();
+static void MITResetProc();
+
+void
+MITMiscExtensionInit()
+{
+ ExtensionEntry *extEntry, *AddExtension();
+
+ if (extEntry = AddExtension(MITMISCNAME, 0, 0,
+ ProcMITDispatch, SProcMITDispatch,
+ MITResetProc, StandardMinorOpcode))
+ MITReqCode = (unsigned char)extEntry->base;
+}
+
+/*ARGSUSED*/
+static void
+MITResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+}
+
+static int
+ProcMITSetBugMode(client)
+ register ClientPtr client;
+{
+ REQUEST(xMITSetBugModeReq);
+
+ REQUEST_SIZE_MATCH(xMITSetBugModeReq);
+ if ((stuff->onOff != xTrue) && (stuff->onOff != xFalse))
+ {
+ client->errorValue = stuff->onOff;
+ return BadValue;
+ }
+ permitOldBugs = stuff->onOff;
+ return(client->noClientException);
+}
+
+static int
+ProcMITGetBugMode(client)
+ register ClientPtr client;
+{
+ REQUEST(xMITGetBugModeReq);
+ xMITGetBugModeReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xMITGetBugModeReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.onOff = permitOldBugs;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xMITGetBugModeReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+static int
+ProcMITDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_MITSetBugMode:
+ return ProcMITSetBugMode(client);
+ case X_MITGetBugMode:
+ return ProcMITGetBugMode(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcMITSetBugMode(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xMITSetBugModeReq);
+
+ swaps(&stuff->length, n);
+ return ProcMITSetBugMode(client);
+}
+
+static int
+SProcMITGetBugMode(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xMITGetBugModeReq);
+
+ swaps(&stuff->length, n);
+ return ProcMITGetBugMode(client);
+}
+
+static int
+SProcMITDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_MITSetBugMode:
+ return SProcMITSetBugMode(client);
+ case X_MITGetBugMode:
+ return SProcMITGetBugMode(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c
new file mode 100644
index 000000000..2d3eb7c42
--- /dev/null
+++ b/Xext/panoramiX.c
@@ -0,0 +1,780 @@
+/* $Xorg: panoramiX.c,v 1.5 2000/08/17 19:47:57 cpqbld Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#define NEED_REPLIES
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "gc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#if 0
+#include <sys/workstation.h>
+#include <X11/Xserver/ws.h>
+#endif
+#include "panoramiX.h"
+#include "panoramiXproto.h"
+
+static unsigned char PanoramiXReqCode = 0;
+/*
+ * PanoramiX data declarations
+ */
+
+int PanoramiXPixWidth;
+int PanoramiXPixHeight;
+int PanoramiXNumScreens;
+
+PanoramiXData *panoramiXdataPtr;
+PanoramiXWindow *PanoramiXWinRoot;
+PanoramiXGC *PanoramiXGCRoot;
+PanoramiXCmap *PanoramiXCmapRoot;
+PanoramiXPmap *PanoramiXPmapRoot;
+
+PanoramiXEdge panoramiXEdgePtr[MAXSCREENS];
+RegionRec PanoramiXScreenRegion[MAXSCREENS];
+PanoramiXCDT PanoramiXColorDepthTable[MAXSCREENS];
+PanoramiXDepth PanoramiXLargestScreenDepth;
+
+int (* SavedProcVector[256]) ();
+ScreenInfo *GlobalScrInfo;
+
+static int panoramiXGeneration;
+static int ProcPanoramiXDispatch();
+/*
+ * Function prototypes
+ */
+
+static void locate_neighbors(int);
+static void PanoramiXResetProc(ExtensionEntry*);
+
+/*
+ * External references for data variables
+ */
+
+extern int SProcPanoramiXDispatch();
+extern Bool noPanoramiXExtension;
+extern Bool PanoramiXVisibilityNotifySent;
+extern WindowPtr *WindowTable;
+#if 0
+extern ScreenArgsRec screenArgs[MAXSCREENS];
+#endif
+extern int defaultBackingStore;
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+extern int (* ProcVector[256]) ();
+
+/*
+ * Server dispatcher function replacements
+ */
+
+int PanoramiXCreateWindow(), PanoramiXChangeWindowAttributes();
+int PanoramiXDestroyWindow(), PanoramiXDestroySubwindows();
+int PanoramiXChangeSaveSet(), PanoramiXReparentWindow();
+int PanoramiXMapWindow(), PanoramiXMapSubwindows();
+int PanoramiXUnmapWindow(), PanoramiXUnmapSubwindows();
+int PanoramiXConfigureWindow(), PanoramiXCirculateWindow();
+int PanoramiXGetGeometry(), PanoramiXChangeProperty();
+int PanoramiXDeleteProperty(), PanoramiXSendEvent();
+int PanoramiXCreatePixmap(), PanoramiXFreePixmap();
+int PanoramiXCreateGC(), PanoramiXChangeGC();
+int PanoramiXCopyGC();
+int PanoramiXSetDashes(), PanoramiXSetClipRectangles();
+int PanoramiXFreeGC(), PanoramiXClearToBackground();
+int PanoramiXCopyArea(), PanoramiXCopyPlane();
+int PanoramiXPolyPoint(), PanoramiXPolyLine();
+int PanoramiXPolySegment(), PanoramiXPolyRectangle();
+int PanoramiXPolyArc(), PanoramiXFillPoly();
+int PanoramiXPolyFillArc(), PanoramiXPolyFillRectangle();
+int PanoramiXPutImage(), PanoramiXGetImage();
+int PanoramiXPolyText8(), PanoramiXPolyText16();
+int PanoramiXImageText8(), PanoramiXImageText16();
+int PanoramiXCreateColormap(), PanoramiXFreeColormap();
+int PanoramiXInstallColormap(), PanoramiXUninstallColormap();
+int PanoramiXAllocColor(), PanoramiXAllocNamedColor();
+int PanoramiXAllocColorCells();
+int PanoramiXFreeColors(), PanoramiXStoreColors();
+
+/*
+ * PanoramiXExtensionInit():
+ * Called from InitExtensions in main().
+ * Register PanoramiXeen Extension
+ * Initialize global variables.
+ */
+
+void PanoramiXExtensionInit(int argc, char *argv[])
+{
+ int i, j, PhyScrNum, ArgScrNum;
+ Bool success = FALSE;
+ ExtensionEntry *extEntry, *AddExtension();
+ PanoramiXData *panoramiXtempPtr;
+ ScreenPtr pScreen;
+
+ if (!noPanoramiXExtension)
+ {
+ GlobalScrInfo = &screenInfo; /* For debug visibility */
+ PanoramiXNumScreens = screenInfo.numScreens;
+ if (PanoramiXNumScreens == 1) { /* Only 1 screen */
+ noPanoramiXExtension = TRUE;
+ return;
+ }
+
+ while (panoramiXGeneration != serverGeneration) {
+ extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
+ ProcPanoramiXDispatch,
+ SProcPanoramiXDispatch, PanoramiXResetProc,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ ErrorF("PanoramiXExtensionInit(): failed to AddExtension\n");
+ break;
+ }
+ PanoramiXReqCode = (unsigned char)extEntry->base;
+
+ /*
+ * First make sure all the basic allocations succeed. If not,
+ * run in non-PanoramiXeen mode.
+ */
+
+ panoramiXdataPtr = (PanoramiXData *) Xcalloc(PanoramiXNumScreens * sizeof(PanoramiXData));
+ PanoramiXWinRoot = (PanoramiXWindow *) Xcalloc(sizeof(PanoramiXWindow));
+ PanoramiXGCRoot = (PanoramiXGC *) Xcalloc(sizeof(PanoramiXGC));
+ PanoramiXCmapRoot = (PanoramiXCmap *) Xcalloc(sizeof(PanoramiXCmap));
+ PanoramiXPmapRoot = (PanoramiXPmap *) Xcalloc(sizeof(PanoramiXPmap));
+ BREAK_IF(!(panoramiXdataPtr && PanoramiXWinRoot && PanoramiXGCRoot &&
+ PanoramiXCmapRoot && PanoramiXPmapRoot));
+
+ panoramiXGeneration = serverGeneration;
+ success = TRUE;
+ }
+
+ if (!success) {
+ noPanoramiXExtension = TRUE;
+ ErrorF("%s Extension failed to initialize\n", PANORAMIX_PROTOCOL_NAME);
+ return;
+ }
+
+ /* Set up a default configuration base on horizontal ordering */
+ for (i = PanoramiXNumScreens -1; i >= 0 ; i--) {
+ panoramiXdataPtr[i].above = panoramiXdataPtr[i].below = -1;
+ panoramiXdataPtr[i].left = panoramiXdataPtr[i].right = -1;
+ panoramiXEdgePtr[i].no_edges = TRUE;
+ }
+ for (i = PanoramiXNumScreens - 1; i >= 0; i--) {
+ panoramiXdataPtr[i].left = i - 1;
+ panoramiXdataPtr[i].right = i + 1;
+ }
+ panoramiXdataPtr[PanoramiXNumScreens - 1].right = -1;
+
+ /*
+ * Position the screens relative to each other based on
+ * command line options.
+ */
+
+#if 0
+ for (PhyScrNum = PanoramiXNumScreens - 1; PhyScrNum >= 0; PhyScrNum--) {
+ if (wsRemapPhysToLogScreens)
+ i = wsPhysToLogScreens[PhyScrNum];
+ else
+ i = PhyScrNum;
+ if (i < 0)
+ continue;
+ panoramiXdataPtr[i].width = (screenInfo.screens[i])->width;
+ panoramiXdataPtr[i].height = (screenInfo.screens[i])->height;
+ if (screenArgs[i].flags & ARG_EDGE_L) {
+ ArgScrNum = screenArgs[PhyScrNum].edge_left;
+ if (ArgScrNum < 0)
+ j = -1;
+ else {
+ if (wsRemapPhysToLogScreens)
+ j = wsPhysToLogScreens[ArgScrNum];
+ else
+ j = ArgScrNum;
+ }
+ panoramiXdataPtr[i].left = j;
+ panoramiXEdgePtr[i].no_edges = FALSE;
+ if ( j >= 0)
+ panoramiXdataPtr[j].right = i;
+ else {
+ if ( i >= 1 )
+ panoramiXdataPtr[i - 1].right = -1;
+ }
+ }
+ if (screenArgs[i].flags & ARG_EDGE_R) {
+ ArgScrNum = screenArgs[PhyScrNum].edge_right;
+ if (ArgScrNum < 0)
+ j = -1;
+ else {
+ if (wsRemapPhysToLogScreens)
+ j = wsPhysToLogScreens[ArgScrNum];
+ else
+ j = ArgScrNum;
+ }
+ panoramiXdataPtr[i].right = j;
+ panoramiXEdgePtr[i].no_edges = FALSE;
+ if ( j >= 0)
+ panoramiXdataPtr[j].left = i;
+ }
+ if (screenArgs[i].flags & ARG_EDGE_T) {
+ ArgScrNum = screenArgs[PhyScrNum].edge_top;
+ if (ArgScrNum < 0)
+ j = -1;
+ else {
+ if (wsRemapPhysToLogScreens)
+ j = wsPhysToLogScreens[ArgScrNum];
+ else
+ j = ArgScrNum;
+ }
+ panoramiXdataPtr[i].above = j;
+ panoramiXEdgePtr[i].no_edges = FALSE;
+ if ( j >= 0)
+ panoramiXdataPtr[j].below = i;
+ }
+ if (screenArgs[i].flags & ARG_EDGE_B) {
+ ArgScrNum = screenArgs[PhyScrNum].edge_bottom;
+ if (ArgScrNum < 0)
+ j = -1;
+ else {
+ if (wsRemapPhysToLogScreens)
+ j = wsPhysToLogScreens[ArgScrNum];
+ else
+ j = ArgScrNum;
+ }
+ panoramiXdataPtr[i].below = j;
+ panoramiXEdgePtr[i].no_edges = FALSE;
+ if ( j >= 0)
+ panoramiXdataPtr[j].above = i;
+ }
+ }
+#else
+ for (PhyScrNum = PanoramiXNumScreens - 1; PhyScrNum >= 0; PhyScrNum--) {
+ i = PhyScrNum;
+ if (i < 0)
+ continue;
+ panoramiXdataPtr[i].width = (screenInfo.screens[i])->width;
+ panoramiXdataPtr[i].height = (screenInfo.screens[i])->height;
+ }
+#endif
+
+ /*
+ * Find the upper-left screen and then locate all the others
+ */
+ panoramiXtempPtr = panoramiXdataPtr;
+ for (i = PanoramiXNumScreens; i; i--, panoramiXtempPtr++)
+ if (panoramiXtempPtr->above == -1 && panoramiXtempPtr->left == -1)
+ break;
+ locate_neighbors(PanoramiXNumScreens - i);
+
+ /*
+ * Put our processes into the ProcVector
+ */
+
+ for (i = 256; i--; )
+ SavedProcVector[i] = ProcVector[i];
+
+ ProcVector[X_CreateWindow] = PanoramiXCreateWindow;
+ ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes;
+ ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow;
+ ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows;
+ ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet;
+ ProcVector[X_ReparentWindow] = PanoramiXReparentWindow;
+ ProcVector[X_MapWindow] = PanoramiXMapWindow;
+ ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows;
+ ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow;
+ ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows;
+ ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow;
+ ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow;
+ ProcVector[X_GetGeometry] = PanoramiXGetGeometry;
+ ProcVector[X_ChangeProperty] = PanoramiXChangeProperty;
+ ProcVector[X_DeleteProperty] = PanoramiXDeleteProperty;
+ ProcVector[X_SendEvent] = PanoramiXSendEvent;
+ ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap;
+ ProcVector[X_FreePixmap] = PanoramiXFreePixmap;
+ ProcVector[X_CreateGC] = PanoramiXCreateGC;
+ ProcVector[X_ChangeGC] = PanoramiXChangeGC;
+ ProcVector[X_CopyGC] = PanoramiXCopyGC;
+ ProcVector[X_SetDashes] = PanoramiXSetDashes;
+ ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles;
+ ProcVector[X_FreeGC] = PanoramiXFreeGC;
+ ProcVector[X_ClearArea] = PanoramiXClearToBackground;
+ ProcVector[X_CopyArea] = PanoramiXCopyArea;;
+ ProcVector[X_CopyPlane] = PanoramiXCopyPlane;;
+ ProcVector[X_PolyPoint] = PanoramiXPolyPoint;
+ ProcVector[X_PolyLine] = PanoramiXPolyLine;
+ ProcVector[X_PolySegment] = PanoramiXPolySegment;
+ ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle;
+ ProcVector[X_PolyArc] = PanoramiXPolyArc;
+ ProcVector[X_FillPoly] = PanoramiXFillPoly;
+ ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle;
+ ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc;
+ ProcVector[X_PutImage] = PanoramiXPutImage;
+ ProcVector[X_GetImage] = PanoramiXGetImage;
+ ProcVector[X_PolyText8] = PanoramiXPolyText8;
+ ProcVector[X_PolyText16] = PanoramiXPolyText16;
+ ProcVector[X_ImageText8] = PanoramiXImageText8;
+ ProcVector[X_ImageText16] = PanoramiXImageText16;
+ ProcVector[X_CreateColormap] = PanoramiXCreateColormap;
+ ProcVector[X_FreeColormap] = PanoramiXFreeColormap;
+ ProcVector[X_InstallColormap] = PanoramiXInstallColormap;
+ ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap;
+ ProcVector[X_AllocColor] = PanoramiXAllocColor;
+ ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor;
+ ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells;
+ ProcVector[X_FreeColors] = PanoramiXFreeColors;
+ ProcVector[X_StoreColors] = PanoramiXStoreColors;
+
+ }
+ else
+ return;
+}
+extern
+Bool PanoramiXCreateConnectionBlock(void)
+{
+ int i;
+ int old_width, old_height;
+ int width_mult, height_mult;
+ xWindowRoot *root;
+ xConnSetup *setup;
+
+ /*
+ * Do normal CreateConnectionBlock but faking it for only one screen
+ */
+
+ if (!CreateConnectionBlock()) {
+ return FALSE;
+ }
+
+ /*
+ * OK, change some dimensions so it looks as if it were one big screen
+ */
+
+ setup = (xConnSetup *) ConnectionInfo;
+ setup->numRoots = 1;
+ root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart);
+
+ old_width = root->pixWidth;
+ old_height = root->pixHeight;
+ for (i = PanoramiXNumScreens - 1; i >= 0; i--) {
+ if (panoramiXdataPtr[i].right == -1 )
+ root->pixWidth = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
+ if (panoramiXdataPtr[i].below == -1)
+ root->pixHeight = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
+ }
+ PanoramiXPixWidth = root->pixWidth;
+ PanoramiXPixHeight = root->pixHeight;
+ width_mult = root->pixWidth / old_width;
+ height_mult = root->pixHeight / old_height;
+ root->mmWidth *= width_mult;
+ root->mmHeight *= height_mult;
+ return TRUE;
+}
+
+extern
+Bool PanoramiXCreateScreenRegion(pWin)
+WindowPtr pWin;
+{
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+ Bool ret;
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0; i < PanoramiXNumScreens; i++) {
+ box.x1 = 0 - panoramiXdataPtr[i].x;
+ box.x2 = box.x1 + PanoramiXPixWidth;
+ box.y1 = 0 - panoramiXdataPtr[i].y;
+ box.y2 = box.y1 + PanoramiXPixHeight;
+ REGION_INIT(pScreen, &PanoramiXScreenRegion[i], &box, 1);
+ ret = REGION_NOTEMPTY(pScreen, &PanoramiXScreenRegion[i]);
+ if (!ret)
+ return ret;
+ }
+ return ret;
+}
+
+extern
+void PanoramiXDestroyScreenRegion(pWin)
+WindowPtr pWin;
+{
+ ScreenPtr pScreen;
+ int i;
+ Bool ret;
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0; i < PanoramiXNumScreens; i++)
+ REGION_DESTROY(pScreen, &PanoramiXScreenRegion[i]);
+}
+
+/*
+ * Assign the Root window and colormap ID's in the PanoramiXScreen Root
+ * linked lists. Note: WindowTable gets setup in dix_main by
+ * InitRootWindow, and GlobalScrInfo is screenInfo which gets setup
+ * by InitOutput.
+ */
+extern
+void PanoramiXConsolidate(void)
+{
+ int i,j,k,v,d,n, thisMaxDepth;
+ int depthIndex;
+ DepthPtr pDepth, pLargeDepth;
+ VisualPtr pVisual;
+ VisualID it;
+ register WindowPtr pWin, pLargeWin;
+ Bool SameDepth;
+
+ PanoramiXLargestScreenDepth.numDepths = (screenInfo.screens[PanoramiXNumScreens -1])->numDepths;
+ PanoramiXLargestScreenDepth.screenNum = PanoramiXNumScreens - 1;
+ SameDepth = TRUE;
+ for (i = 0; i < 2; i++)
+ {
+ for (j =0; j < 6; j++)
+ {
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[j].numDepths=0;
+ for (n = 0; n < 6; n++)
+ {
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[j].listDepths[n]=0;
+ }
+ for (k = 0; k < 33; k++)
+ {
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[j].vmap[k].numVids=0;
+ for (v = 0; v < 10; v++)
+ {
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[j].vmap[k].vid[v]=0;
+ }
+ }
+ }
+ }
+ for (i = PanoramiXNumScreens - 1; i >= 0; i--)
+ {
+ PanoramiXWinRoot->info[i].id = WindowTable[i]->drawable.id;
+ PanoramiXCmapRoot->info[i].id = (screenInfo.screens[i])->defColormap;
+
+ /* Create a Color-Depth-Table, this will help us deal
+ with mixing graphics boards and visuals, of course
+ given that the boards support multi-screen to begin
+ with. Fill the panoramiXCDT table by screen, then
+ visual type and allowable depths.
+ */
+ pWin = WindowTable[i];
+ if ( (screenInfo.screens[i])->numDepths >
+ PanoramiXLargestScreenDepth.numDepths )
+ {
+ PanoramiXLargestScreenDepth.numDepths = (screenInfo.screens[i])->numDepths;
+ PanoramiXLargestScreenDepth.screenNum = i;
+ SameDepth = FALSE;
+ }
+ for (v = 0, pVisual = pWin->drawable.pScreen->visuals;
+ v < pWin->drawable.pScreen->numVisuals; v++, pVisual++)
+ {
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[pVisual->class].numDepths = (screenInfo.screens[i])->numDepths;
+ for ( j = 0; j < (screenInfo.screens[i])->numDepths; j++)
+ {
+ pDepth = (DepthPtr) &pWin->drawable.pScreen->allowedDepths[j];
+ PanoramiXColorDepthTable[i].panoramiXScreenMap[pVisual->class].listDepths[j] = pDepth->depth;
+ for (d = 0; d < pDepth->numVids; d++)
+ {
+ if (pVisual->vid == pDepth->vids[d])
+ {
+ PanoramiXColorDepthTable[i].
+ panoramiXScreenMap[pVisual->class].vmap[pDepth->depth].
+ vid[
+ PanoramiXColorDepthTable[i].
+ panoramiXScreenMap[pVisual->class].
+ vmap[pDepth->depth].numVids++
+ ]
+ = pDepth->vids[d];
+ }
+ }
+ }
+ }
+ PanoramiXColorDepthTable[i].numVisuals = 6;
+ } /* for each screen */
+ /* Fill in ColorDepthTable for mixed visuals with varying depth.
+ Can't do that until we figure out how to handle mixed visuals
+ and varying card visual/depth initialization. If we can decide
+ how to map the relationship, then we can use this table to
+ shove the information into and use for cross-referencing when
+ necessary.
+
+ In the meantime, check to see if the screens are the same,
+ if they don't then disable panoramiX, print out a message,
+ don't support this mode.
+ */
+}
+
+/* Since locate_neighbors is recursive, a quick simple example
+ is in order.This mostly so you can see what the initial values are.
+
+ Given 3 screens:
+ upperleft screen[0]
+ panoramiXdataPtr[0].x = 0
+ panoramiXdataPtr[0].y = 0
+ panoramiXdataPtr[0].width = 640
+ panoramiXdataPtr[0].height = 480
+ panoramiXdataPtr[0].below = -1
+ panoramiXdataPtr[0].right = 1
+ panoramiXdataPtr[0].above = -1
+ panoramiXdataPtr[0].left = -1
+ middle screen[1]
+ panoramiXdataPtr[1].x = 0
+ panoramiXdataPtr[1].y = 0
+ panoramiXdataPtr[1].width = 640
+ panoramiXdataPtr[1].height = 480
+ panoramiXdataPtr[1].below = -1
+ panoramiXdataPtr[1].right = 2
+ panoramiXdataPtr[1].above = -1
+ panoramiXdataPtr[1].left = 0
+ last right screen[2]
+ panoramiXdataPtr[2].x = 0
+ panoramiXdataPtr[2].y = 0
+ panoramiXdataPtr[2].width = 640
+ panoramiXdataPtr[2].height = 480
+ panoramiXdataPtr[2].below = -1
+ panoramiXdataPtr[2].right = -1
+ panoramiXdataPtr[2].above = -1
+ panoramiXdataPtr[2].left = 1
+
+ Calling locate_neighbors(0) results in:
+ panoramiXdataPtr[0].x = 0
+ panoramiXdataPtr[0].y = 0
+ panoramiXdataPtr[1].x = 640
+ panoramiXdataPtr[1].y = 0
+ panoramiXdataPtr[2].x = 1280
+ panoramiXdataPtr[2].y = 0
+*/
+
+static void locate_neighbors(int i)
+{
+ int j;
+
+ j = panoramiXdataPtr[i].right;
+ if ((j != -1) && !panoramiXdataPtr[j].x && !panoramiXdataPtr[j].y) {
+ panoramiXdataPtr[j].x = panoramiXdataPtr[i].x + panoramiXdataPtr[i].width;
+ panoramiXdataPtr[j].y = panoramiXdataPtr[i].y;
+ locate_neighbors(j);
+ }
+ j = panoramiXdataPtr[i].below;
+ if ((j != -1) && !panoramiXdataPtr[j].x && !panoramiXdataPtr[j].y) {
+ panoramiXdataPtr[j].y = panoramiXdataPtr[i].y + panoramiXdataPtr[i].height;
+ panoramiXdataPtr[j].x = panoramiXdataPtr[i].x;
+ locate_neighbors(j);
+ }
+}
+
+
+
+/*
+ * PanoramiXResetProc()
+ * Exit, deallocating as needed.
+ */
+
+static void PanoramiXResetProc(extEntry)
+ ExtensionEntry* extEntry;
+{
+ int i;
+ PanoramiXList *pPanoramiXList;
+ PanoramiXList *tempList;
+
+ for (pPanoramiXList = PanoramiXPmapRoot; pPanoramiXList; pPanoramiXList = tempList){
+ tempList = pPanoramiXList->next;
+ Xfree(pPanoramiXList);
+ }
+ for (pPanoramiXList = PanoramiXCmapRoot; pPanoramiXList; pPanoramiXList = tempList){
+ tempList = pPanoramiXList->next;
+ Xfree(pPanoramiXList);
+ }
+ for (pPanoramiXList = PanoramiXGCRoot; pPanoramiXList; pPanoramiXList = tempList) {
+ tempList = pPanoramiXList->next;
+ Xfree(pPanoramiXList);
+ }
+ for (pPanoramiXList = PanoramiXWinRoot; pPanoramiXList; pPanoramiXList = tempList) {
+ tempList = pPanoramiXList->next;
+ Xfree(pPanoramiXList);
+ }
+ screenInfo.numScreens = PanoramiXNumScreens;
+ for (i = 256; i--; )
+ ProcVector[i] = SavedProcVector[i];
+ Xfree(panoramiXdataPtr);
+
+}
+
+
+int
+#if NeedFunctionPrototypes
+ProcPanoramiXQueryVersion (ClientPtr client)
+#else
+ProcPanoramiXQueryVersion (client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ xPanoramiXQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = PANORAMIX_MAJOR_VERSION;
+ rep.minorVersion = PANORAMIX_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+int
+#if NeedFunctionPrototypes
+ProcPanoramiXGetState(ClientPtr client)
+#else
+ProcPanoramiXGetState(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPanoramiXExtension;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.state, n);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
+ return client->noClientException;
+
+}
+
+int
+#if NeedFunctionPrototypes
+ProcPanoramiXGetScreenCount(ClientPtr client)
+#else
+ProcPanoramiXGetScreenCount(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = PanoramiXNumScreens;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.ScreenCount, n);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep);
+ return client->noClientException;
+}
+
+int
+#if NeedFunctionPrototypes
+ProcPanoramiXGetScreenSize(ClientPtr client)
+#else
+ProcPanoramiXGetScreenSize(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ /* screen dimensions */
+ rep.width = panoramiXdataPtr[stuff->screen].width;
+ rep.height = panoramiXdataPtr[stuff->screen].height;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (rep.width, n);
+ swaps (rep.height, n);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep);
+ return client->noClientException;
+}
+
+
+void PrintList(PanoramiXList *head)
+{
+ int i = 0;
+
+ for (; head; i++, head = head->next)
+ fprintf(stderr, "%2d next = 0x%010lx, id[0] = 0x%08x, id[1] = 0x%08x\n",
+ i, head->next, head->info[0].id, head->info[1].id);
+}
+static int
+#if NeedFunctionPrototypes
+ProcPanoramiXDispatch (ClientPtr client)
+#else
+ProcPanoramiXDispatch (client)
+ ClientPtr client;
+#endif
+{ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return ProcPanoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return ProcPanoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return ProcPanoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return ProcPanoramiXGetScreenSize(client);
+ }
+ return BadRequest;
+}
diff --git a/Xext/panoramiXSwap.c b/Xext/panoramiXSwap.c
new file mode 100644
index 000000000..c6bb5071e
--- /dev/null
+++ b/Xext/panoramiXSwap.c
@@ -0,0 +1,158 @@
+/* $Xorg: panoramiXSwap.c,v 1.4 2000/08/17 19:47:57 cpqbld Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "gc.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#if 0
+#include <sys/workstation.h>
+#include <X11/Xserver/ws.h>
+#endif
+#include "panoramiX.h"
+#include "panoramiXproto.h"
+
+
+/*
+/*
+ * External references for data variables
+ */
+
+extern Bool noPanoramiXExtension;
+extern Bool PanoramiXVisibilityNotifySent;
+extern WindowPtr *WindowTable;
+extern int defaultBackingStore;
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+extern int (* ProcVector[256]) ();
+
+#if NeedFunctionPrototypes
+#define PROC_EXTERN(pfunc) extern int pfunc(ClientPtr)
+#else
+#define PROC_EXTERN(pfunc) extern int pfunc()
+#endif
+
+PROC_EXTERN(ProcPanoramiXQueryVersion);
+PROC_EXTERN(ProcPanoramiXGetState);
+PROC_EXTERN(ProcPanoramiXGetScreenCount);
+PROC_EXTERN(PropPanoramiXGetScreenSize);
+
+static int
+#if NeedFunctionPrototypes
+SProcPanoramiXQueryVersion (ClientPtr client)
+#else
+SProcPanoramiXQueryVersion (client)
+ register ClientPtr client;
+#endif
+{
+ register int n;
+ REQUEST(xPanoramiXQueryVersionReq);
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return ProcPanoramiXQueryVersion(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcPanoramiXGetState(ClientPtr client)
+#else
+SProcPanoramiXGetState(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetStateReq);
+ register int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcPanoramiXGetScreenCount(ClientPtr client)
+#else
+SProcPanoramixGetScreenCount(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ register int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return ProcPanoramiXGetScreenCount(client);
+}
+
+static int
+#if NeedFunctionPrototypes
+SProcPanoramiXGetScreenSize(ClientPtr client)
+#else
+SProcPanoramiXGetScreenSize(client)
+ register ClientPtr client;
+#endif
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ register int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return ProcPanoramiXGetScreenSize(client);
+}
+
+int
+#if NeedFunctionPrototypes
+SProcPanoramiXDispatch (ClientPtr client)
+#else
+SProcPanoramiXDispatch (client)
+ ClientPtr client;
+#endif
+{ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return SProcPanoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SProcPanoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SProcPanoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SProcPanoramiXGetScreenSize(client);
+ return BadRequest;
+ }
+}
diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c
new file mode 100644
index 000000000..cd54bdcb3
--- /dev/null
+++ b/Xext/panoramiXprocs.c
@@ -0,0 +1,3034 @@
+/* $Xorg: panoramiXprocs.c,v 1.5 2000/08/17 19:47:57 cpqbld Exp $ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#include <stdio.h>
+#include "X.h"
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "Xproto.h"
+#include "windowstr.h"
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "inputstr.h"
+#include "migc.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "panoramiX.h"
+
+extern Bool noPanoramiXExtension;
+extern Bool PanoramiXVisibilityNotifySent;
+extern Bool PanoramiXMapped;
+extern int PanoramiXNumScreens;
+extern int PanoramiXPixWidth;
+extern int PanoramiXPixHeight;
+extern PanoramiXWindow *PanoramiXWinRoot;
+extern PanoramiXGC *PanoramiXGCRoot;
+extern PanoramiXCmap *PanoramiXCmapRoot;
+extern PanoramiXPmap *PanoramiXPmapRoot;
+extern PanoramiXData *panoramiXdataPtr;
+extern PanoramiXCDT PanoramiXColorDepthTable[MAXSCREENS];
+extern ScreenInfo *GlobalScrInfo;
+extern int (* SavedProcVector[256])();
+extern void (* ReplySwapVector[256])();
+extern WindowPtr *WindowTable;
+extern char *ConnectionInfo;
+extern int connBlockScreenStart;
+
+extern XID clientErrorValue;
+
+extern void Swap32Write();
+
+extern long defaultScreenSaverTime;
+extern long defaultScreenSaverInterval;
+extern int defaultScreenSaverBlanking;
+extern int defaultScreenSaverAllowExposures;
+static ClientPtr onlyClient;
+static Bool grabbingClient = FALSE;
+#ifdef __alpha /* THIS NEEDS TO BE LONG !!!! Change driver! */
+int *checkForInput[2];
+#else
+long *checkForInput[2];
+#endif
+extern int connBlockScreenStart;
+
+extern int (* InitialVector[3]) ();
+extern int (* ProcVector[256]) ();
+extern int (* SwappedProcVector[256]) ();
+extern void (* EventSwapVector[128]) ();
+extern void (* ReplySwapVector[256]) ();
+extern void Swap32Write(), SLHostsExtend(), SQColorsExtend(),
+WriteSConnectionInfo();
+extern void WriteSConnSetupPrefix();
+extern char *ClientAuthorized();
+extern Bool InsertFakeRequest();
+static void KillAllClients();
+static void DeleteClientFromAnySelections();
+extern void ProcessWorkQueue();
+
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number active clients */
+
+char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+
+
+extern int Ones();
+
+int PanoramiXCreateWindow(register ClientPtr client)
+{
+ register WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int result, j = 0;
+ unsigned len;
+ Bool FoundIt = FALSE;
+ Window winID;
+ Window parID;
+ PanoramiXWindow *localWin;
+ PanoramiXWindow *parentWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXCmap *pPanoramiXCmap = NULL;
+ PanoramiXPmap *pBackgndPmap = NULL;
+ PanoramiXPmap *pBorderPmap = NULL;
+ VisualID orig_visual;
+ XID orig_wid;
+ int orig_x, orig_y;
+ register Mask orig_mask;
+ int cmap_offset = 0;
+ int pback_offset = 0;
+ int pbord_offset = 0;
+ int class_index, this_class_index;
+ int vid_index, this_vid_index;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ IF_RETURN((Ones((Mask)stuff->mask) != len), BadLength);
+ orig_mask = stuff->mask;
+ PANORAMIXFIND_ID(parentWin, stuff->parent);
+ if (parentWin) {
+ localWin = (PanoramiXWindow *)Xcalloc(sizeof(PanoramiXWindow));
+ IF_RETURN(!localWin, BadAlloc);
+ } else {
+ return BadWindow;
+ }
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->mask & CWBackPixmap)) {
+ XID pmapID;
+
+ pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
+ pmapID = *((CARD32 *) &stuff[1] + pback_offset);
+ if (pmapID) {
+ pBackgndPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pBackgndPmap, pmapID);
+ }
+ }
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->mask & CWBorderPixmap)) {
+ XID pmapID;
+
+ pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
+ pmapID = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (pmapID) {
+ pBorderPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pBorderPmap, pmapID);
+ }
+ }
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->mask & CWColormap)) {
+ Colormap cmapID;
+
+ cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
+ cmapID = *((CARD32 *) &stuff[1] + cmap_offset);
+ if (cmapID) {
+ pPanoramiXCmap = PanoramiXCmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXCmap, cmapID);
+ }
+ }
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ orig_wid = stuff->wid;
+ orig_visual = stuff->visual;
+ for (j = 0; j <= PanoramiXNumScreens - 1; j++) {
+ winID = j ? FakeClientID(client->index) : orig_wid;
+ localWin->info[j].id = winID;
+ }
+ localWin->FreeMe = FALSE;
+ localWin->visibility = VisibilityNotViewable;
+ localWin->VisibilitySent = FALSE;
+ PANORAMIXFIND_LAST(pPanoramiXWin, PanoramiXWinRoot);
+ pPanoramiXWin->next = localWin;
+ if ( (stuff->visual != CopyFromParent) && (stuff->depth != 0))
+ {
+ /* Find the correct visual for this screen */
+ for (class_index = 0; class_index < PanoramiXColorDepthTable[0].numVisuals;
+class_index++)
+ {
+ for (vid_index = 0; vid_index < PanoramiXColorDepthTable[0].panoramiXScreenMap[class_index].vmap[stuff->depth].numVids; vid_index++)
+ {
+ if ( stuff->visual == PanoramiXColorDepthTable[0].panoramiXScreenMap[class_index].vmap[stuff->depth].vid[vid_index] )
+ {
+ this_class_index = class_index;
+ this_vid_index = vid_index;
+ FoundIt = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ if (parentWin == PanoramiXWinRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ stuff->wid = localWin->info[j].id;
+ parID = (XID)(parentWin->info[j].id);
+ pParent = (WindowPtr)SecurityLookupWindow(parID, client,SecurityReadAccess);
+ IF_RETURN((!pParent),BadWindow);
+ stuff->parent = parID;
+ if ( (orig_visual != CopyFromParent) && (stuff->depth != 0) && FoundIt )
+ {
+ stuff->visual = PanoramiXColorDepthTable[j].panoramiXScreenMap[this_class_index].vmap[stuff->depth].vid[this_vid_index];
+ }
+ if (pBackgndPmap)
+ *((CARD32 *) &stuff[1] + pback_offset) = pBackgndPmap->info[j].id;
+ if (pBorderPmap)
+ *((CARD32 *) &stuff[1] + pbord_offset) = pBorderPmap->info[j].id;
+ if (pPanoramiXCmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = pPanoramiXCmap->info[j].id;
+ stuff->mask = orig_mask;
+ result = (*SavedProcVector[X_CreateWindow])(client);
+ BREAK_IF(result != Success);
+ }
+ if (result != Success) {
+ pPanoramiXWin->next = NULL;
+ if (localWin)
+ Xfree(localWin);
+ }
+ return (result);
+}
+
+
+
+int PanoramiXChangeWindowAttributes(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ register int result;
+ int len;
+ int j;
+ Window winID;
+ Mask orig_valueMask;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXWinback = NULL;
+ PanoramiXCmap *pPanoramiXCmap = NULL;
+ PanoramiXPmap *pBackgndPmap = NULL;
+ PanoramiXPmap *pBorderPmap = NULL;
+ int cmap_offset = 0;
+ int pback_offset = 0;
+ int pbord_offset = 0;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ IF_RETURN((len != Ones((Mask) stuff->valueMask)), BadLength);
+ orig_valueMask = stuff->valueMask;
+ winID = stuff->window;
+ for (; pPanoramiXWin && (pPanoramiXWin->info[0].id != stuff->window);
+ pPanoramiXWin = pPanoramiXWin->next)
+ pPanoramiXWinback = pPanoramiXWin;
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, winID);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->valueMask & CWBackPixmap)) {
+ XID pmapID;
+
+ pback_offset = Ones((Mask)stuff->valueMask & (CWBackPixmap - 1));
+ pmapID = *((CARD32 *) &stuff[1] + pback_offset);
+ if (pmapID) {
+ pBackgndPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pBackgndPmap, pmapID);
+ }
+ }
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->valueMask & CWBorderPixmap)) {
+ XID pmapID;
+
+ pbord_offset = Ones((Mask)stuff->valueMask & (CWBorderPixmap - 1));
+ pmapID = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (pmapID) {
+ pBorderPmap = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pBorderPmap, pmapID);
+ }
+ }
+ if ((PanoramiXNumScreens - 1) && ((Mask)stuff->valueMask & CWColormap )) {
+ Colormap cmapID;
+
+ cmap_offset = Ones((Mask)stuff->valueMask & (CWColormap - 1));
+ cmapID = *((CARD32 *) &stuff[1] + cmap_offset);
+ if (cmapID) {
+ pPanoramiXCmap = PanoramiXCmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXCmap, cmapID);
+ }
+ }
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ stuff->valueMask = orig_valueMask;
+ if (pBackgndPmap)
+ *((CARD32 *) &stuff[1] + pback_offset) = pBackgndPmap->info[j].id;
+ if (pBorderPmap)
+ *((CARD32 *) &stuff[1] + pbord_offset) = pBorderPmap->info[j].id;
+ if (pPanoramiXCmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = pPanoramiXCmap->info[j].id;
+ result = (*SavedProcVector[X_ChangeWindowAttributes])(client);
+ BREAK_IF(result != Success);
+ }
+ if ((result == Success) && pPanoramiXWinback &&
+ pPanoramiXWin && pPanoramiXWin->FreeMe) {
+ pPanoramiXWinback->next = pPanoramiXWin->next;
+ Xfree(pPanoramiXWin);
+ }
+ return (result);
+}
+
+
+int PanoramiXDestroyWindow(ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j, result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXWinback = NULL;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ for (; pPanoramiXWin && (pPanoramiXWin->info[0].id != stuff->id);
+ pPanoramiXWin = pPanoramiXWin->next)
+ pPanoramiXWinback = pPanoramiXWin;
+ IF_RETURN(!pPanoramiXWin,BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->id = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_DestroyWindow])(client);
+ BREAK_IF(result != Success);
+ }
+ if ((result == Success) && pPanoramiXWinback &&
+ pPanoramiXWin && pPanoramiXWin->FreeMe) {
+ pPanoramiXWinback->next = pPanoramiXWin->next;
+ Xfree(pPanoramiXWin);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXDestroySubwindows(ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j,result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXWinback = NULL;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ for (; pPanoramiXWin && (pPanoramiXWin->info[0].id != stuff->id);
+ pPanoramiXWin = pPanoramiXWin->next)
+ pPanoramiXWinback = pPanoramiXWin;
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->id = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_DestroySubwindows])(client);
+ }
+ if ((result == Success) && pPanoramiXWinback &&
+ pPanoramiXWin && pPanoramiXWin->FreeMe) {
+ pPanoramiXWinback->next = pPanoramiXWin->next;
+ Xfree(pPanoramiXWin);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXChangeSaveSet(ClientPtr client)
+{
+ REQUEST(xChangeSaveSetReq);
+ int j, result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ if (!stuff->window)
+ result = (* SavedProcVector[X_ChangeSaveSet])(client);
+ else {
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_ChangeSaveSet])(client);
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXReparentWindow(register ClientPtr client)
+{
+ register WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXPar = PanoramiXWinRoot;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ PANORAMIXFIND_ID(pPanoramiXPar, stuff->parent);
+ IF_RETURN(!pPanoramiXPar, BadWindow);
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXPar), j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ stuff->parent = pPanoramiXPar->info[j].id;
+ result = (*SavedProcVector[X_ReparentWindow])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXMapWindow(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j,result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ register WindowPtr pWin, pChild;
+ Window winID;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ /* initialize visibility */
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->id, client,
+SecurityReadAccess);
+ IF_RETURN(!pWin, BadWindow);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pChild->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->id);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ PanoramiXMapped = TRUE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ for (j = 0; j <= (PanoramiXNumScreens - 1); j++)
+ {
+ winID = pPanoramiXWin->info[j].id;
+ pWin = (WindowPtr) SecurityLookupWindow(winID,
+client,SecurityReadAccess);
+ IF_RETURN((!pWin), BadWindow);
+ stuff->id = winID;
+ result = (*SavedProcVector[X_MapWindow])(client);
+ }
+ /* clean up */
+ PanoramiXMapped = FALSE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib){
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pChild->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+ return (result);
+}
+
+
+int PanoramiXMapSubwindows(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j,result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ register WindowPtr pWin, pChild;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ /* initialize visibility values */
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ IF_RETURN(!pWin, BadWindow);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib){
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pChild->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->id);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ PanoramiXMapped = TRUE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ for (j = 0; j <= (PanoramiXNumScreens - 1); j++)
+ {
+ stuff->id = pPanoramiXWin->info[j].id;
+ result = (*SavedProcVector[X_MapSubwindows])(client);
+ }
+ /* clean up */
+ PanoramiXMapped = FALSE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pChild->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXUnmapWindow(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j, result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ register WindowPtr pWin, pChild;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ /* initialize visibility values */
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ IF_RETURN(!pWin, BadWindow);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib){
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pWin->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->id);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ PanoramiXMapped = TRUE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ for (j = 0; j <= (PanoramiXNumScreens - 1); j++)
+ {
+ stuff->id = pPanoramiXWin->info[j].id;
+ result = (*SavedProcVector[X_UnmapWindow])(client);
+ }
+
+ /* clean up */
+ PanoramiXMapped = FALSE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) {
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pChild->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+ PANORAMIX_FREE(client);
+ return (client->noClientException);
+}
+
+
+int PanoramiXUnmapSubwindows(register ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ int j, result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ register WindowPtr pWin, pChild;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ /* initialize visibility values */
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ IF_RETURN(!pWin, BadWindow);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib){
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pWin->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->id);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ PanoramiXMapped = TRUE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ for (j = 0; j <= (PanoramiXNumScreens - 1); j++)
+ {
+ stuff->id = pPanoramiXWin->info[j].id;
+ result = (*SavedProcVector[X_UnmapSubwindows])(client);
+ }
+
+ /* clean up */
+ PanoramiXMapped = FALSE;
+ PanoramiXVisibilityNotifySent = FALSE;
+ pPanoramiXWin->VisibilitySent = FALSE;
+ pWin = (WindowPtr) SecurityLookupWindow(stuff->id,
+client,SecurityReadAccess);
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib){
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, pWin->drawable.id);
+ if (pPanoramiXWin)
+ pPanoramiXWin->VisibilitySent = FALSE;
+ }
+ PANORAMIX_FREE(client);
+ return (client->noClientException);
+}
+
+
+int PanoramiXConfigureWindow(register ClientPtr client)
+{
+ register WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ register int result;
+ unsigned len, i, things;
+ XID changes[32];
+ register Mask orig_mask;
+ int j, sib_position;
+ Window winID;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXWindow *pPanoramiXSib = NULL;
+ int x_off = 0, y_off = 0;
+ XID *pStuff;
+ XID *origStuff, *modStuff;
+ Mask local_mask;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ things = Ones((Mask)stuff->mask);
+ IF_RETURN((things != len), BadLength);
+ orig_mask = stuff->mask;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ if (!pPanoramiXWin) {
+ client->errorValue = stuff->window;
+ return (BadWindow);
+ }
+ if (things > 0) {
+ pStuff = (XID *) ALLOCATE_LOCAL(things * sizeof(XID));
+ memcpy((char *) pStuff, (char *) &stuff[1], things * sizeof(XID));
+ local_mask = (CWSibling | CWX | CWY) & ((Mask) stuff->mask);
+ if (local_mask & CWSibling) {
+ sib_position = Ones((Mask) stuff->mask & (CWSibling - 1));
+ pPanoramiXSib = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXSib, *(pStuff + sib_position));
+ }
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ winID = pPanoramiXWin->info[j].id;
+ pWin = (WindowPtr)SecurityLookupWindow(winID, client,SecurityReadAccess);
+ if (!pWin) {
+ client->errorValue = pPanoramiXWin->info[0].id;
+ return (BadWindow);
+ }
+ stuff->window = winID;
+ if (pWin->parent
+ && (pWin->parent->drawable.id == PanoramiXWinRoot->info[j].id)) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ modStuff = (XID *) &stuff[1];
+ origStuff = pStuff;
+ i = things;
+ if (local_mask & CWX) {
+ *modStuff++ = *origStuff++ - x_off;
+ i--;
+ }
+ if (local_mask & CWY) {
+ *modStuff++ = *origStuff++ - y_off;
+ i--;
+ }
+ for ( ; i; i--)
+ *modStuff++ = *origStuff++;
+ if (pPanoramiXSib)
+ *((XID *) &stuff[1] + sib_position) = pPanoramiXSib->info[j].id;
+ stuff->mask = orig_mask;
+ result = (*SavedProcVector[X_ConfigureWindow])(client);
+ }
+ DEALLOCATE_LOCAL(pStuff);
+ PANORAMIX_FREE(client);
+ return (result);
+ } else
+ return (client->noClientException);
+}
+
+
+int PanoramiXCirculateWindow(register ClientPtr client)
+{
+ REQUEST(xCirculateWindowReq);
+ int j,result;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = (*SavedProcVector[X_CirculateWindow])(client);
+ }
+ return (result);
+}
+
+
+int PanoramiXGetGeometry(register ClientPtr client)
+{
+ xGetGeometryReply rep;
+ register DrawablePtr pDraw;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ VERIFY_GEOMETRABLE (pDraw, stuff->id, client);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep.depth = pDraw->depth;
+
+ if (stuff->id == PanoramiXWinRoot->info[0].id) {
+ xConnSetup *setup = (xConnSetup *) ConnectionInfo;
+ xWindowRoot *root = (xWindowRoot *)
+ (ConnectionInfo + connBlockScreenStart);
+
+ rep.width = root->pixWidth;
+ rep.height = root->pixHeight;
+ } else {
+ rep.width = pDraw->width;
+ rep.height = pDraw->height;
+ }
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id))) {
+ register WindowPtr pWin = (WindowPtr)pDraw;
+ rep.x = pWin->origin.x - wBorderWidth (pWin);
+ rep.y = pWin->origin.y - wBorderWidth (pWin);
+ rep.borderWidth = pWin->borderWidth;
+ } else { /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ rep.x = rep.y = rep.borderWidth = 0;
+ }
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return (client->noClientException);
+}
+
+
+int PanoramiXChangeProperty(ClientPtr client)
+{
+ int result, j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ REQUEST(xChangePropertyReq);
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_ChangeProperty])(client);
+ if (result != Success) {
+ stuff->window = pPanoramiXWin->info[0].id;
+ break;
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXDeleteProperty(ClientPtr client)
+{
+ int result, j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ REQUEST(xDeletePropertyReq);
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xDeletePropertyReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->window = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_DeleteProperty])(client);
+ BREAK_IF(result != Success);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXSendEvent(ClientPtr client)
+{
+ int result, j;
+ BYTE orig_type;
+ Mask orig_eventMask;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ REQUEST(xSendEventReq);
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->destination);
+ orig_type = stuff->event.u.u.type;
+ orig_eventMask = stuff->eventMask;
+ if (!pPanoramiXWin) {
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_SendEvent])(client);
+ noPanoramiXExtension = FALSE;
+ }
+ else {
+ noPanoramiXExtension = FALSE;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->destination = pPanoramiXWin->info[j].id;
+ stuff->eventMask = orig_eventMask;
+ stuff->event.u.u.type = orig_type;
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_SendEvent])(client);
+ noPanoramiXExtension = FALSE;
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXCreatePixmap(register ClientPtr client)
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ int result, j;
+ Pixmap pmapID;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXPmap *pPanoramiXPmap;
+ PanoramiXPmap *localPmap;
+ XID orig_pid;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+
+ localPmap =(PanoramiXPmap *) Xcalloc(sizeof(PanoramiXPmap));
+ IF_RETURN(!localPmap, BadAlloc);
+
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!pDraw, BadDrawable);
+
+ pPanoramiXWin = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+
+ orig_pid = stuff->pid;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXPmap, j) {
+ pmapID = j ? FakeClientID(client->index) : orig_pid;
+ localPmap->info[j].id = pmapID;
+ }
+ localPmap->FreeMe = FALSE;
+ PANORAMIXFIND_LAST(pPanoramiXPmap, PanoramiXPmapRoot);
+ pPanoramiXPmap->next = localPmap;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->pid = localPmap->info[j].id;
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ result = (* SavedProcVector[X_CreatePixmap])(client);
+ BREAK_IF(result != Success);
+ }
+ if (result != Success) {
+ pPanoramiXPmap->next = NULL;
+ if (localPmap)
+ Xfree(localPmap);
+ }
+ return (result);
+}
+
+
+int PanoramiXFreePixmap(ClientPtr client)
+{
+ PixmapPtr pMap;
+ int result, j;
+ PanoramiXPmap *pPanoramiXPmap = PanoramiXPmapRoot;
+ PanoramiXPmap *pPanoramiXPmapback = NULL;
+ REQUEST(xResourceReq);
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ for (; pPanoramiXPmap && (pPanoramiXPmap->info[0].id != stuff->id);
+ pPanoramiXPmap = pPanoramiXPmap->next)
+ pPanoramiXPmapback = pPanoramiXPmap;
+ if (!pPanoramiXPmap)
+ result = (* SavedProcVector[X_FreePixmap])(client);
+ else {
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->id = pPanoramiXPmap->info[j].id;
+ result = (* SavedProcVector[X_FreePixmap])(client);
+ }
+ if ((result == Success) && pPanoramiXPmapback &&
+ pPanoramiXPmap && pPanoramiXPmap->FreeMe ) {
+ pPanoramiXPmapback->next = pPanoramiXPmap->next;
+ Xfree(pPanoramiXPmap);
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXCreateGC(register ClientPtr client)
+{
+ int result, j;
+ GC *pGC;
+ DrawablePtr pDraw;
+ unsigned len, i;
+ REQUEST(xCreateGCReq);
+ GContext GCID;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *localGC;
+ PanoramiXGC *pPanoramiXGC;
+ PanoramiXPmap *pPanoramiXTile = NULL, *pPanoramiXStip = NULL;
+ PanoramiXPmap *pPanoramiXClip = NULL;
+ int tile_offset, stip_offset, clip_offset;
+ XID orig_GC;
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!pDraw, BadDrawable);
+ pPanoramiXWin = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+
+ len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ IF_RETURN((len != Ones((Mask)stuff->mask)), BadLength);
+ localGC = (PanoramiXGC *) Xcalloc(sizeof(PanoramiXGC));
+ IF_RETURN(!localGC, BadAlloc);
+ orig_GC = stuff->gc;
+ if ((Mask)stuff->mask & GCTile) {
+ XID tileID;
+
+ tile_offset = Ones((Mask)stuff->mask & (GCTile - 1));
+ tileID = *((CARD32 *) &stuff[1] + tile_offset);
+ if (tileID) {
+ pPanoramiXTile = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXTile, tileID);
+ }
+ }
+ if ((Mask)stuff->mask & GCStipple) {
+ XID stipID;
+
+ stip_offset = Ones((Mask)stuff->mask & (GCStipple - 1));
+ stipID = *((CARD32 *) &stuff[1] + stip_offset);
+ if (stipID) {
+ pPanoramiXStip = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXStip, stipID);
+ }
+ }
+ if ((Mask)stuff->mask & GCClipMask) {
+ XID clipID;
+
+ clip_offset = Ones((Mask)stuff->mask & (GCClipMask - 1));
+ clipID = *((CARD32 *) &stuff[1] + clip_offset);
+ if (clipID) {
+ pPanoramiXClip = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXClip, clipID);
+ }
+ }
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGC, j) {
+ GCID = j ? FakeClientID(client->index) : orig_GC;
+ localGC->info[j].id = GCID;
+ }
+ localGC->FreeMe = FALSE;
+ PANORAMIXFIND_LAST(pPanoramiXGC, PanoramiXGCRoot);
+ pPanoramiXGC->next = localGC;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->gc = localGC->info[j].id;
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ if (pPanoramiXTile)
+ *((CARD32 *) &stuff[1] + tile_offset) = pPanoramiXTile->info[j].id;
+ if (pPanoramiXStip)
+ *((CARD32 *) &stuff[1] + stip_offset) = pPanoramiXStip->info[j].id;
+ if (pPanoramiXClip)
+ *((CARD32 *) &stuff[1] + clip_offset) = pPanoramiXClip->info[j].id;
+ result = (* SavedProcVector[X_CreateGC])(client);
+ BREAK_IF(result != Success);
+ }
+ if (result != Success) {
+ pPanoramiXGC->next = NULL;
+ Xfree(localGC);
+ }
+ return (result);
+}
+
+
+int PanoramiXChangeGC(ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xChangeGCReq);
+ int result, j;
+ unsigned len;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ PanoramiXPmap *pPanoramiXTile = NULL, *pPanoramiXStip = NULL;
+ PanoramiXPmap *pPanoramiXClip = NULL;
+ int tile_offset, stip_offset, clip_offset;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+ VERIFY_GC(pGC, stuff->gc, client);
+ len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ IF_RETURN((len != Ones((Mask)stuff->mask)), BadLength);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ if ((Mask)stuff->mask & GCTile) {
+ XID tileID;
+
+ tile_offset = Ones((Mask)stuff->mask & (GCTile -1) );
+ tileID = *((CARD32 *) &stuff[1] + tile_offset);
+ if (tileID) {
+ pPanoramiXTile = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXTile, tileID);
+ }
+ }
+ if ((Mask)stuff->mask & GCStipple) {
+ XID stipID;
+
+ stip_offset = Ones((Mask)stuff->mask & (GCStipple -1 ));
+ stipID = *((CARD32 *) &stuff[1] + stip_offset);
+ if (stipID) {
+ pPanoramiXStip = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXStip, stipID);
+ }
+ }
+ if ((Mask)stuff->mask & GCClipMask) {
+ XID clipID;
+
+ clip_offset = Ones((Mask)stuff->mask & (GCClipMask -1));
+ clipID = *((CARD32 *) &stuff[1] + clip_offset);
+ if (clipID) {
+ pPanoramiXClip = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXClip, clipID);
+ }
+ }
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGC, j) {
+ stuff->gc = pPanoramiXGC->info[j].id;
+ if (pPanoramiXTile)
+ *((CARD32 *) &stuff[1] + tile_offset) = pPanoramiXTile->info[j].id;
+ if (pPanoramiXStip)
+ *((CARD32 *) &stuff[1] + stip_offset) = pPanoramiXStip->info[j].id;
+ if (pPanoramiXClip)
+ *((CARD32 *) &stuff[1] + clip_offset) = pPanoramiXClip->info[j].id;
+ result = (* SavedProcVector[X_ChangeGC])(client);
+ BREAK_IF(result != Success);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXCopyGC(ClientPtr client)
+{
+ int j, result;
+ PanoramiXGC *pPanoramiXGCSrc = PanoramiXGCRoot;
+ PanoramiXGC *pPanoramiXGCDst = PanoramiXGCRoot;
+ REQUEST(xCopyGCReq);
+
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+ PANORAMIXFIND_ID(pPanoramiXGCSrc, stuff->srcGC);
+ IF_RETURN(!pPanoramiXGCSrc, BadGC);
+ PANORAMIXFIND_ID(pPanoramiXGCDst, stuff->dstGC);
+ IF_RETURN(!pPanoramiXGCDst, BadGC);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGCDst, j) {
+ stuff->srcGC = pPanoramiXGCSrc->info[j].id;
+ stuff->dstGC = pPanoramiXGCDst->info[j].id;
+ result = (* SavedProcVector[X_CopyGC])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXSetDashes(ClientPtr client)
+{
+ GC *pGC;
+ REQUEST(xSetDashesReq);
+ int result, j;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ VERIFY_GC(pGC, stuff->gc, client);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGC, j) {
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_SetDashes])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXSetClipRectangles(register ClientPtr client)
+{
+ int result;
+ register GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+ int j;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGC, j) {
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_SetClipRectangles])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXFreeGC(ClientPtr client)
+{
+ register GC *pGC;
+ REQUEST(xResourceReq);
+ int result, j;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ PanoramiXGC *pPanoramiXGCback = NULL;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ for (; pPanoramiXGC && (pPanoramiXGC->info[0].id != stuff->id);
+ pPanoramiXGC = pPanoramiXGC->next)
+ pPanoramiXGCback = pPanoramiXGC;
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXGC, j) {
+ stuff->id = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_FreeGC])(client);
+ BREAK_IF(result != Success);
+ }
+ if ((result == Success) && pPanoramiXGCback &&
+ pPanoramiXGC && pPanoramiXGC->FreeMe) {
+ pPanoramiXGCback->next = pPanoramiXGC->next;
+ if (pPanoramiXGC)
+ Xfree(pPanoramiXGC);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXClearToBackground(register ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ register WindowPtr pWin;
+ int result, j;
+ Window winID;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ int orig_x, orig_y;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ winID = pPanoramiXWin->info[j].id;
+ pWin = (WindowPtr) SecurityLookupWindow(winID, client, SecurityReadAccess);
+ if (!pWin) {
+ client->errorValue = pPanoramiXWin->info[0].id;
+ return (BadWindow);
+ }
+ stuff->window = winID;
+ if (pWin->drawable.id == PanoramiXWinRoot->info[j].id) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = (*SavedProcVector[X_ClearArea])(client);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXCopyArea(ClientPtr client)
+{
+ int j, result;
+ Window srcID, dstID;
+ DrawablePtr pSrc, pDst;
+ GContext GCID;
+ GC *pGC;
+ PanoramiXWindow *pPanoramiXSrcRoot;
+ PanoramiXWindow *pPanoramiXDstRoot;
+ PanoramiXWindow *pPanoramiXSrc;
+ PanoramiXWindow *pPanoramiXDst;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ REQUEST(xCopyAreaReq);
+ int srcx = stuff->srcX, srcy = stuff->srcY;
+ int dstx = stuff->dstX, dsty = stuff->dstY;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable) {
+ VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client);
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ } else {
+ pSrc = pDst;
+ }
+ pPanoramiXSrcRoot = (pSrc->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXDstRoot = (pDst->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXSrc = pPanoramiXSrcRoot;
+ pPanoramiXDst = pPanoramiXDstRoot;
+ PANORAMIXFIND_ID(pPanoramiXSrc, stuff->srcDrawable);
+ IF_RETURN(!pPanoramiXSrc, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXDst, stuff->dstDrawable);
+ IF_RETURN(!pPanoramiXDst, BadDrawable);
+ GCID = stuff->gc;
+ PANORAMIXFIND_ID(pPanoramiXGC, GCID);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+
+ FOR_NSCREENS_OR_ONCE(pPanoramiXSrc, j) {
+ stuff->dstDrawable = pPanoramiXDst->info[j].id;
+ stuff->srcDrawable = pPanoramiXSrc->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ if (pPanoramiXSrc == pPanoramiXSrcRoot) {
+ stuff->srcX = srcx - panoramiXdataPtr[j].x;
+ stuff->srcY = srcy - panoramiXdataPtr[j].y;
+ }
+ if (pPanoramiXDst == pPanoramiXDstRoot) {
+ stuff->dstX = dstx - panoramiXdataPtr[j].x;
+ stuff->dstY = dsty - panoramiXdataPtr[j].y;
+ }
+ result = (* SavedProcVector[X_CopyArea])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+int PanoramiXCopyPlane(ClientPtr client)
+{
+ int SrcScr = -1, DstScr = -1;
+ PixmapPtr pMap = NULL;
+ Pixmap pmapID;
+ PanoramiXRect SrcRect, DstRect;
+ int i, j, k;
+ Window srcID, dstID;
+ DrawablePtr pSrc, pDst;
+ GContext GCID;
+ GContext GCIDbase;
+ GC *pGC;
+ PanoramiXWindow *pPanoramiXSrc;
+ PanoramiXWindow *pPanoramiXDst;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ RegionPtr *PanoramiXRgnPtrs;
+ RegionPtr *FetchRgnPtrs = NULL;
+ RegionPtr pRgn;
+ REQUEST(xCopyPlaneReq);
+ int srcx = stuff->srcX, srcy = stuff->srcY;
+ int dstx = stuff->dstX, dsty = stuff->dstY;
+ int width = stuff->width, height = stuff->height;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, pGC, client);
+ if (stuff->dstDrawable != stuff->srcDrawable) {
+ VERIFY_DRAWABLE(pSrc, stuff->srcDrawable, client);
+ if (pDst->pScreen != pSrc->pScreen) {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ } else {
+ pSrc = pDst;
+ }
+
+ /*
+ * Check to see if stuff->bitPlane has exactly ONE good bit set
+ */
+
+
+ if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+ (stuff->bitPlane > (1L << (pSrc->depth - 1))))
+ {
+ client->errorValue = stuff->bitPlane;
+ return(BadValue);
+ }
+
+ pPanoramiXSrc = (pSrc->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXDst = (pDst->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXSrc, stuff->srcDrawable);
+ IF_RETURN(!pPanoramiXSrc, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXDst, stuff->dstDrawable);
+ IF_RETURN(!pPanoramiXDst, BadDrawable);
+ GCIDbase = stuff->gc;
+ PANORAMIXFIND_ID(pPanoramiXGC, GCIDbase);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+
+ /*
+ * Unless both are pixmaps, need to do special things to accomodate
+ * being on multiple screens, different screens, etc.
+ */
+
+ if (pSrc->type != DRAWABLE_PIXMAP) {
+ SrcRect.x = pSrc->x + srcx;
+ SrcRect.y = pSrc->y + srcy;
+ SrcRect.width = width;
+ SrcRect.height = height;
+ for (SrcScr = PanoramiXNumScreens - 1; SrcScr>=0; SrcScr-- )
+ if (RECTA_SUBSUMES_RECTB(panoramiXdataPtr[SrcScr], SrcRect))
+ break;
+ }
+ if (pDst->type != DRAWABLE_PIXMAP) {
+ DstRect.x = pDst->x + dstx;
+ DstRect.y = pDst->y + dsty;
+ DstRect.width = width;
+ DstRect.height = height;
+ for (DstScr = PanoramiXNumScreens - 1; DstScr>=0; DstScr--)
+ if (RECTA_SUBSUMES_RECTB(panoramiXdataPtr[DstScr], DstRect))
+ break;
+ }
+
+ /*
+ * If source is on multiple screens, different screen from destination,
+ * destination is on multiple screens, or destination is a pixmap,
+ * need to get info into local pixmap for subsequent transfer.
+ */
+
+
+ if ((pSrc->type != DRAWABLE_PIXMAP) &&
+ (SrcScr < 0 || DstScr < 0 || SrcScr != DstScr
+ || pDst->type == DRAWABLE_PIXMAP)) {
+ unsigned char save_alu;
+ RegionRec tempReg;
+ RegionPtr pCompositeClip;
+ PanoramiXPmap *pPanoramiXPmap = PanoramiXPmapRoot;
+
+ pMap = (PixmapPtr) (*pSrc->pScreen->CreatePixmap)(pSrc->pScreen,
+ width, height, pGC->depth);
+ PANORAMIXFIND_LAST(pPanoramiXPmap, PanoramiXPmapRoot);
+ pPanoramiXPmap->next =
+ (PanoramiXPmap *)Xcalloc(sizeof(PanoramiXPmap));
+ pPanoramiXPmap = pPanoramiXPmap->next;
+ pmapID = FakeClientID(0);
+ AddResource(pmapID, RT_PIXMAP, (pointer)pMap);
+ for (j = PanoramiXNumScreens - 1; j>=0; j--)
+ pPanoramiXPmap->info[j].id = pmapID;
+ tempReg.extents.x1 = 0;
+ tempReg.extents.y1 = 0;
+ tempReg.extents.x2 = width;
+ tempReg.extents.y2 = height;
+ tempReg.data = NULL;
+ FetchRgnPtrs =
+ (RegionPtr *) ALLOCATE_LOCAL(PanoramiXNumScreens * sizeof(RegionPtr));
+ i = 0;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXSrc, j) {
+ if ((SrcScr >= 0) && pPanoramiXSrc)
+ j = SrcScr;
+ srcID = pPanoramiXSrc->info[j].id;
+ pSrc = (DrawablePtr) SecurityLookupIDByClass(client, srcID, RC_DRAWABLE,
+ SecurityReadAccess);
+ GCID = pPanoramiXGC->info[j].id;
+ pGC = (GC *) LookupIDByType(GCID, RT_GC);
+ pMap->drawable.pScreen = pSrc->pScreen;
+ pGC->pScreen = pSrc->pScreen;
+ save_alu = pGC->alu;
+ pGC->alu = GXcopy;
+ pCompositeClip = ((miPrivGC*)
+ (pGC->devPrivates[miGCPrivateIndex].ptr))->pCompositeClip;
+ ((miPrivGC*)(pGC->devPrivates[miGCPrivateIndex].ptr))->pCompositeClip =
+&tempReg;
+ FetchRgnPtrs[i++] = (*pGC->ops->CopyPlane)(pSrc, (DrawablePtr) pMap,
+ pGC, srcx, srcy, width, height, 0, 0, stuff->bitPlane);
+ pGC->alu = save_alu;
+ ((miPrivGC*) (pGC->devPrivates[miGCPrivateIndex].ptr))->pCompositeClip =
+pCompositeClip;
+ if (SrcScr >= 0)
+ j = 0;
+ }
+ }
+
+ if (pMap) {
+ pSrc = (DrawablePtr) pMap;
+ srcx = 0;
+ srcy = 0;
+ }
+ PanoramiXRgnPtrs =
+ (RegionPtr *) ALLOCATE_LOCAL(PanoramiXNumScreens * sizeof(RegionPtr));
+ k = 0;
+ /* if src and dst are entirely on one screen,
+ then we only need one simple transfer */
+ if ((DstScr >= 0) && (pMap || (SrcScr >=0))) {
+ dstID = pPanoramiXDst->info[DstScr].id;
+ pDst = (DrawablePtr) SecurityLookupIDByClass(client, dstID, RC_DRAWABLE,
+ SecurityReadAccess);
+ GCID = pPanoramiXGC->info[DstScr].id;
+ pGC = (GC *) LookupIDByType(GCID, RT_GC);
+ ValidateGC(pDst, pGC);
+ if (pMap) {
+ pMap->drawable.pScreen = pDst->pScreen;
+ } else {
+ srcID = pPanoramiXSrc->info[SrcScr].id;
+ if (srcID != dstID) {
+ pSrc = (DrawablePtr) SecurityLookupIDByClass(client, srcID, RC_DRAWABLE,
+ SecurityReadAccess);
+ } else
+ pSrc = pDst;
+ }
+ if (pMap)
+ PanoramiXRgnPtrs[k++] = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ 1);
+ else
+ PanoramiXRgnPtrs[k++] = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ stuff->bitPlane);
+ }else {
+ FOR_NSCREENS_OR_ONCE(pPanoramiXDst, j) {
+ if (DstScr >= 0) {
+ dstID = pPanoramiXDst->info[DstScr].id;
+ GCID = pPanoramiXGC->info[DstScr].id;
+ } else {
+ dstID = pPanoramiXDst->info[j].id;
+ GCID = pPanoramiXGC->info[j].id;
+ }
+ pDst = (DrawablePtr) SecurityLookupIDByClass(client, dstID, RC_DRAWABLE,
+ SecurityReadAccess);
+ pGC = (GC *) LookupIDByType(GCID, RT_GC);
+ ValidateGC(pDst, pGC);
+ if (pMap) {
+ pMap->drawable.pScreen = pDst->pScreen;
+ } else {
+ srcID = pPanoramiXSrc->info[j].id;
+ if (srcID != dstID) {
+ pSrc = (DrawablePtr) SecurityLookupIDByClass(client, srcID, RC_DRAWABLE,
+ SecurityReadAccess);
+ } else {
+ pSrc = pDst;
+ }
+ }
+ if (pMap)
+ PanoramiXRgnPtrs[k++] = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ 1);
+ else
+ PanoramiXRgnPtrs[k++] = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ stuff->bitPlane);
+ }
+ }
+
+ if (pMap) {
+ for (j = PanoramiXNumScreens - 1; j>=0; j--)
+ if (PanoramiXRgnPtrs[j])
+ (*pDst->pScreen->RegionDestroy) (PanoramiXRgnPtrs[j]);
+ DEALLOCATE_LOCAL(PanoramiXRgnPtrs);
+ PanoramiXRgnPtrs = FetchRgnPtrs;
+ k = i;
+ }
+ j = 1;
+ i = 0;
+ pRgn = PanoramiXRgnPtrs[i];
+ while ((j < k) && pRgn && !REGION_NIL(pRgn)) {
+ if (PanoramiXRgnPtrs[j]) {
+ (*pGC->pScreen->Intersect)(pRgn, pRgn, PanoramiXRgnPtrs[j++]);
+ } else {
+ pRgn = PanoramiXRgnPtrs[i++];
+ }
+ }
+ for (j = 0 ; j < k; j++) {
+ pRgn = PanoramiXRgnPtrs[j];
+ GCID = pPanoramiXGC->info[j].id;
+ pGC = (GC *) LookupIDByType(GCID, RT_GC);
+ if (pGC && pGC->graphicsExposures)
+ (*pDst->pScreen->SendGraphicsExpose) (client, pRgn,
+ stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ (*pDst->pScreen->RegionDestroy) (pRgn);
+ }
+ DEALLOCATE_LOCAL(PanoramiXRgnPtrs);
+ if (pMap) {
+ PanoramiXPmap *pPanoramiXPmap = PanoramiXPmapRoot;
+ PanoramiXPmap *pback = PanoramiXPmapRoot;
+
+ for (; pPanoramiXPmap && (pPanoramiXPmap->info[0].id != pmapID);
+ pPanoramiXPmap = pPanoramiXPmap->next)
+ pback = pPanoramiXPmap;
+ FreeResource(pPanoramiXPmap->info[0].id, RT_NONE);
+ if (pback) {
+ pback->next = pPanoramiXPmap->next;
+ Xfree(pPanoramiXPmap);
+ }
+ }
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyPoint(ClientPtr client)
+{
+ int result, npoint, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ int x_off = 0, y_off = 0;
+ xPoint *origPts;
+ xPoint *origPtr, *modPtr;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, locDraw->id);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ if (npoint > 0) {
+ origPts = (xPoint *) ALLOCATE_LOCAL(npoint * sizeof(xPoint));
+ memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xPoint *) &stuff[1];
+ origPtr = origPts;
+ for (i = npoint; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr++->y = origPtr++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyPoint])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origPts);
+ return (result);
+ }else
+ return (client->noClientException);
+
+}
+
+
+int PanoramiXPolyLine(ClientPtr client)
+{
+ int result, npoint, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ int x_off = 0, y_off = 0;
+ xPoint *origPts;
+ xPoint *origPtr, *modPtr;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, locDraw->id);
+ /* In the case of Multibuffering, we need to make sure the drawable
+ isn't really a pixmap associated to a drawable */
+ if (!pPanoramiXWin && (stuff->drawable != locDraw->id)) {
+ pPanoramiXWin = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ }
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ if (npoint > 0){
+ origPts = (xPoint *) ALLOCATE_LOCAL(npoint * sizeof(xPoint));
+ memcpy((char *) origPts, (char *) &stuff[1], npoint * sizeof(xPoint));
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xPoint *) &stuff[1];
+ origPtr = origPts;
+ for (i = npoint; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr++->y = origPtr++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyLine])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origPts);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolySegment(ClientPtr client)
+{
+ int result, nsegs, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ int x_off = 0, y_off = 0;
+ xSegment *origSegs;
+ xSegment *origPtr, *modPtr;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ /* In the case of Multibuffering, we need to make sure the drawable
+ isn't really a pixmap associated to a drawable */
+ if (!pPanoramiXWin && (stuff->drawable != locDraw->id)) {
+ pPanoramiXWin = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ }
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ IF_RETURN((nsegs & 4), BadLength);
+ nsegs >>= 3;
+ if (nsegs > 0) {
+ origSegs = (xSegment *) ALLOCATE_LOCAL(nsegs * sizeof(xSegment));
+ memcpy((char *) origSegs, (char *) &stuff[1], nsegs *
+sizeof(xSegment));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xSegment *) &stuff[1];
+ origPtr = origSegs;
+ for (i = nsegs; i; i--) {
+ modPtr->x1 = origPtr->x1 - x_off;
+ modPtr->y1 = origPtr->y1 - y_off;
+ modPtr->x2 = origPtr->x2 - x_off;
+ modPtr++->y2 = origPtr++->y2 - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolySegment])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origSegs);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyRectangle(ClientPtr client)
+{
+ int result, nrects, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ int x_off = 0, y_off = 0;
+ xRectangle *origRecs;
+ xRectangle *origPtr, *modPtr;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ IF_RETURN((nrects & 4), BadLength);
+ nrects >>= 3;
+ if (nrects > 0){
+ origRecs = (xRectangle *) ALLOCATE_LOCAL(nrects * sizeof(xRectangle));
+ memcpy((char *) origRecs, (char *) &stuff[1], nrects *
+sizeof(xRectangle));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xRectangle *) &stuff[1];
+ origPtr = origRecs;
+ for (i = nrects; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr->y = origPtr->y - y_off;
+ modPtr->width = origPtr->width - x_off;
+ modPtr++->height = origPtr++->height - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyRectangle])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origRecs);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyArc(ClientPtr client)
+{
+ int result, narcs, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ GCPtr locGC;
+ int x_off = 0, y_off = 0;
+ xArc *origArcs;
+ xArc *origPtr, *modPtr;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot :
+PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ IF_RETURN((narcs % sizeof(xArc)), BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs > 0){
+ origArcs = (xArc *) ALLOCATE_LOCAL(narcs * sizeof(xArc));
+ memcpy((char *) origArcs, (char *) &stuff[1], narcs * sizeof(xArc));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xArc *) &stuff[1];
+ origPtr = origArcs;
+ for (i = narcs; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr++->y = origPtr++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyArc])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origArcs);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXFillPoly(ClientPtr client)
+{
+ int result, count, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ GCPtr locGC;
+ int x_off = 0, y_off = 0;
+ DDXPointPtr locPts;
+ DDXPointPtr origPts, modPts;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ count = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ if (count > 0){
+ locPts = (DDXPointPtr) ALLOCATE_LOCAL(count * sizeof(DDXPointRec));
+ memcpy((char *) locPts, (char *) &stuff[1], count *
+sizeof(DDXPointRec));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPts = (DDXPointPtr) &stuff[1];
+ origPts = locPts;
+ for (i = count; i; i--) {
+ modPts->x = origPts->x - x_off;
+ modPts++->y = origPts++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_FillPoly])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(locPts);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyFillRectangle(ClientPtr client)
+{
+ int result, things, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ GCPtr locGC;
+ int x_off = 0, y_off = 0;
+ xRectangle *origThings;
+ xRectangle *origPtr, *modPtr;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot :
+PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ IF_RETURN((things & 4), BadLength);
+ things >>= 3;
+ if (things > 0){
+ origThings = (xRectangle *) ALLOCATE_LOCAL(things * sizeof(xRectangle));
+ memcpy((char *) origThings, (char *)&stuff[1], things *
+sizeof(xRectangle));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xRectangle *) &stuff[1];
+ origPtr = origThings;
+ for (i = things; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr++->y = origPtr++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyFillRectangle])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origThings);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+int PanoramiXPolyFillArc(ClientPtr client)
+{
+ int result, arcs, i, j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr locDraw;
+ GCPtr locGC;
+ int x_off = 0, y_off = 0;
+ xArc *origArcs;
+ xArc *origPtr, *modPtr;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!locDraw, BadDrawable);
+ pPanoramiXWin = (locDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot :
+PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ arcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ IF_RETURN((arcs % sizeof(xArc)), BadLength);
+ arcs /= sizeof(xArc);
+ if (arcs > 0) {
+ origArcs = (xArc *) ALLOCATE_LOCAL(arcs * sizeof(xArc));
+ memcpy((char *) origArcs, (char *)&stuff[1], arcs * sizeof(xArc));
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ if (pPanoramiXWin == PanoramiXWinRoot) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }else {
+ if ( (locDraw->type == DRAWABLE_PIXMAP) &&
+ /* add special case check for root window */
+ (locDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ x_off = panoramiXdataPtr[j].x;
+ y_off = panoramiXdataPtr[j].y;
+ }
+ }
+ modPtr = (xArc *) &stuff[1];
+ origPtr = origArcs;
+ for (i = arcs; i; i--) {
+ modPtr->x = origPtr->x - x_off;
+ modPtr++->y = origPtr++->y - y_off;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PolyFillArc])(client);
+ BREAK_IF(result != Success);
+ }
+ DEALLOCATE_LOCAL(origArcs);
+ return (result);
+ }else
+ return (client->noClientException);
+}
+
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+
+int PanoramiXPutImage(register ClientPtr client)
+{
+ register GC *pGC;
+ register DrawablePtr pDraw;
+ long lengthProto, /* length of scanline protocl padded */
+ length; /* length of scanline server padded */
+ char *tmpImage;
+ int j;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXWindow *pPanoramiXRoot;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ int orig_x, orig_y;
+ int result;
+
+
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ pDraw = (DrawablePtr) SecurityLookupIDByClass(client, stuff->drawable,
+RC_DRAWABLE,
+ SecurityReadAccess);
+ IF_RETURN(!pDraw, BadDrawable);
+ pPanoramiXRoot = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXWin = pPanoramiXRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin,BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ orig_x = stuff->dstX;
+ orig_y = stuff->dstY;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ if (pPanoramiXWin == pPanoramiXRoot) {
+ stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ if (pDraw->type == DRAWABLE_PIXMAP) {
+ if (stuff->width > panoramiXdataPtr[j].width)
+ stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+ if (stuff->height > panoramiXdataPtr[j].height)
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ result = (* SavedProcVector[X_PutImage])(client);
+ }
+ return(result);
+}
+
+
+typedef struct _SrcParts{
+ int x1, y1, x2, y2, width, ByteWidth;
+ char *buf;
+} SrcPartsRec;
+
+
+int PanoramiXGetImage(register ClientPtr client)
+{
+ register DrawablePtr pDraw;
+ int nlines, linesPerBuf;
+ register int height, linesDone;
+ long widthBytesLine, length;
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ long widthBytesLineProto, lengthProto;
+ char *tmpImage;
+#endif
+ Mask plane;
+ char *pBuf;
+ xGetImageReply xgi;
+ int j, k, ScrNum;
+ DrawablePtr locDraw;
+ SrcPartsRec srcParts;
+ BoxRec SrcBox;
+ char *BufPtr, *PartPtr;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST(xGetImageReq);
+
+ height = stuff->height;
+ REQUEST_SIZE_MATCH(xGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ ScrNum = 0;
+ if (stuff->drawable == PanoramiXWinRoot->info[0].id) {
+ for (j = 0; j <= (PanoramiXNumScreens - 1); j++) {
+ ScrNum = j;
+ VERIFY_DRAWABLE(pDraw, pPanoramiXWin->info[ScrNum].id, client);
+ if (stuff->x < panoramiXdataPtr[ScrNum].x &&
+ stuff->y < panoramiXdataPtr[ScrNum].y )
+ break;
+ }
+ }
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ if (!((WindowPtr) pDraw)->realized /* Check for viewable */
+ || pDraw->x + stuff->x < 0 /* Check for on screen */
+ || pDraw->x + stuff->x + (int)stuff->width > PanoramiXPixWidth
+ || pDraw->y + stuff->y < 0
+ || pDraw->y + stuff->y + height > PanoramiXPixHeight
+ || stuff->x < - wBorderWidth((WindowPtr)pDraw) /* Inside border */
+ || stuff->x + (int)stuff->width >
+ wBorderWidth((WindowPtr)pDraw) + (int) pDraw->width
+ + panoramiXdataPtr[ScrNum].x
+ || stuff->y < -wBorderWidth((WindowPtr)pDraw)
+ || stuff->y + height >
+ wBorderWidth ((WindowPtr)pDraw) + (int) pDraw->height
+ + panoramiXdataPtr[ScrNum].y)
+ return(BadMatch);
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ xgi.visual = wVisual (((WindowPtr) pDraw));
+ pPanoramiXWin = PanoramiXWinRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadWindow);
+ } else {
+ if (stuff->x < 0 || stuff->x + (int)stuff->width > pDraw->width
+ || stuff->y < 0 || stuff->y + height > pDraw->height)
+ return(BadMatch);
+ xgi.visual = None;
+ }
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if (stuff->format == ZPixmap) {
+ widthBytesLine = PixmapBytePad(stuff->width, pDraw->depth);
+ length = widthBytesLine * height;
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ widthBytesLineProto = PixmapBytePadProto(stuff->width, pDraw->depth);
+ lengthProto = widthBytesLineProto * height;
+#endif
+ } else {
+ widthBytesLine = BitmapBytePad(stuff->width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(stuff->planeMask & (plane | (plane - 1)));
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ widthBytesLineProto = BitmapBytePadProto(stuff->width);
+ lengthProto = widthBytesLineProto * height *
+ Ones(stuff->planeMask & (plane | (plane - 1)));
+#endif
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ xgi.length = (lengthProto + 3) >> 2;
+#else
+ xgi.length = (length + 3) >> 2;
+#endif
+
+ if (widthBytesLine == 0 || height == 0) {
+ linesPerBuf = 0;
+ } else if (widthBytesLine >= IMAGE_BUFSIZE) {
+ linesPerBuf = 1;
+ } else {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height) {
+
+ /*
+ * Have to make sure intermediate buffers don't need padding
+ */
+
+ while ((linesPerBuf > 1)
+ && (length & ((1 << LOG2_BYTES_PER_SCANLINE_PAD)-1))) {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1 << LOG2_BYTES_PER_SCANLINE_PAD)-1)) {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ IF_RETURN((!(pBuf = (char *) ALLOCATE_LOCAL(length))), BadAlloc);
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /*
+ * Check for protocol/server padding differences
+ */
+
+ if (widthBytesLine != widthBytesLineProto)
+ if (!(tmpImage = (char *) ALLOCATE_LOCAL(length))) {
+ DEALLOCATE_LOCAL(pBuf);
+ return (BadAlloc);
+ }
+#endif
+
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+
+ if (linesPerBuf == 0) {
+
+ /*
+ * Nothing to do
+ */
+
+ } else if (stuff->format == ZPixmap) {
+ linesDone = 0;
+ while (height - linesDone > 0) {
+ nlines = min(linesPerBuf, height - linesDone);
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ SrcBox.x1 = pDraw->x + stuff->x;
+ SrcBox.y1 = pDraw->y + stuff->y + linesDone;
+ SrcBox.x2 = SrcBox.x1 + stuff->width;
+ SrcBox.y2 = SrcBox.y1 + nlines;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+
+ /*
+ * If it isn't even on this screen, just continue.
+ */
+
+ if ((SrcBox.x1 >= panoramiXdataPtr[j].x + panoramiXdataPtr[j].width)
+ || (SrcBox.x2 <= panoramiXdataPtr[j].x)
+ || (SrcBox.y1 >= panoramiXdataPtr[j].y+panoramiXdataPtr[j].height)
+ || (SrcBox.y2 <= panoramiXdataPtr[j].y))
+ continue;
+
+ srcParts.x1 = max(SrcBox.x1 - panoramiXdataPtr[j].x, 0);
+ srcParts.x2 = min(SrcBox.x2 - panoramiXdataPtr[j].x,
+ panoramiXdataPtr[j].width);
+ srcParts.y1 = max(SrcBox.y1 - panoramiXdataPtr[j].y, 0);
+ srcParts.y2 = min(SrcBox.y2 - panoramiXdataPtr[j].y,
+ panoramiXdataPtr[j].height);
+ srcParts.width = srcParts.x2 - srcParts.x1;
+ srcParts.ByteWidth = PixmapBytePad(srcParts.width,pDraw->depth);
+ srcParts.buf = (char *) Xalloc(nlines * srcParts.ByteWidth);
+ locDraw = (DrawablePtr) SecurityLookupIDByClass(client,
+ pPanoramiXWin->info[j].id,
+ RC_DRAWABLE,
+ SecurityReadAccess);
+ (*pDraw->pScreen->GetImage)(locDraw,
+ srcParts.x1 - locDraw->x,
+ srcParts.y1 - locDraw->y,
+ srcParts.width,
+ srcParts.y2 - srcParts.y1,
+ stuff->format,
+ (unsigned long)stuff->planeMask,
+ srcParts.buf);
+ BufPtr = pBuf
+ + srcParts.x1 - stuff->x - (pDraw->x - panoramiXdataPtr[j].x)
+ + widthBytesLine * (srcParts.y1 - stuff->y
+ - (pDraw->y + linesDone - panoramiXdataPtr[j].y));
+ PartPtr = srcParts.buf;
+ for (k = (srcParts.y2 - srcParts.y1); k; k--) {
+ bcopy(PartPtr, BufPtr, srcParts.width);
+ BufPtr += widthBytesLine;
+ PartPtr += srcParts.ByteWidth;
+ }
+ Xfree(srcParts.buf);
+ }
+ } else {
+ (*pDraw->pScreen->GetImage) (pDraw, stuff->x, stuff->y + linesDone,
+ stuff->width, nlines, stuff->format,
+ (unsigned long)stuff->planeMask, pBuf);
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /*
+ * For 64-bit server, convert image to pad to 32 bits
+ */
+
+ if ( widthBytesLine != widthBytesLineProto ) {
+ register char * bufPtr, * protoPtr;
+ register int i;
+
+ bzero(tmpImage,length);
+
+ for (i = 0, bufPtr = pBuf, protoPtr = tmpImage; i < nlines;
+ bufPtr += widthBytesLine, protoPtr += widthBytesLineProto,
+ i++)
+ memmove(protoPtr,bufPtr,widthBytesLineProto);
+
+ /*
+ * Note this is NOT a call to WriteSwappedDataToClient,
+ * as we do NOT byte swap
+ */
+
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLineProto), tmpImage);
+ } else
+#endif
+ {
+
+ /*
+ * Note this is NOT a call to WriteSwappedDataToClient,
+ * as we do NOT byte swap
+ */
+
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine), pBuf);
+ }
+ linesDone += nlines;
+ }
+ } else { /* XYPixmap */
+ for (; plane; plane >>= 1) {
+ if (stuff->planeMask & plane) {
+ linesDone = 0;
+ while (height - linesDone > 0) {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ stuff->x,
+ stuff->y + linesDone,
+ stuff->width,
+ nlines,
+ stuff->format,
+ (unsigned long)plane,
+ pBuf);
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /*
+ * For 64-bit server, convert image to pad to 32 bits
+ */
+
+ if (widthBytesLine != widthBytesLineProto) {
+ register char * bufPtr, * protoPtr;
+ register int i;
+
+ bzero(tmpImage, length);
+
+ for (i = 0,bufPtr = pBuf,protoPtr =tmpImage; i < nlines;
+ bufPtr += widthBytesLine,
+ protoPtr += widthBytesLineProto,
+ i++)
+ bcopy(bufPtr, protoPtr, widthBytesLineProto);
+
+ /*
+ * Note: NOT a call to WriteSwappedDataToClient,
+ * as we do NOT byte swap
+ */
+
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLineProto), tmpImage);
+ } else
+#endif
+ {
+
+ /*
+ * Note: NOT a call to WriteSwappedDataToClient,
+ * as we do NOT byte swap
+ */
+
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine), pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+ DEALLOCATE_LOCAL(pBuf);
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ if (widthBytesLine != widthBytesLineProto)
+ DEALLOCATE_LOCAL(tmpImage);
+#endif
+ return (client->noClientException);
+}
+
+
+int
+PanoramiXPolyText8(register ClientPtr client)
+{
+ int result, j;
+
+ PanoramiXWindow *pPanoramiXRoot;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr pDraw;
+ PixmapPtr pPixmap;
+ GC *pGC;
+ int orig_x, orig_y;
+ REQUEST(xPolyTextReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ pPanoramiXRoot = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXWin = pPanoramiXRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ /* In the case of Multibuffering, we need to make sure the drawable
+ isn't really a pixmap associated to a drawable */
+ if (!pPanoramiXWin && (stuff->drawable != pDraw->id)) {
+ pPanoramiXWin = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ }
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ stuff->x = orig_x;
+ stuff->y = orig_y;
+ if (pPanoramiXWin == pPanoramiXRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ } else {
+ if ( (pDraw->type == DRAWABLE_PIXMAP) &&
+ /* special case root window bitmap */
+ (pDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ }
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (*SavedProcVector[X_PolyText8])(client);
+ noPanoramiXExtension = FALSE;
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+int
+PanoramiXPolyText16(register ClientPtr client)
+{
+ int result, j;
+
+ PanoramiXWindow *pPanoramiXRoot;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr pDraw;
+ GC *pGC;
+ int orig_x, orig_y;
+ REQUEST(xPolyTextReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ pPanoramiXRoot = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXWin = pPanoramiXRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ /* In the case of Multibuffering, we need to make sure the drawable
+ isn't really a pixmap associated to a drawable */
+ if (!pPanoramiXWin && (stuff->drawable != pDraw->id)) {
+ pPanoramiXWin = PanoramiXPmapRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ }
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ stuff->x = orig_x;
+ stuff->y = orig_y;
+ if (pPanoramiXWin == pPanoramiXRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ } else {
+ if ( (pDraw->type == DRAWABLE_PIXMAP) &&
+ /* special case root window bitmap */
+ (pDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ }
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (*SavedProcVector[X_PolyText16])(client);
+ noPanoramiXExtension = FALSE;
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+
+int PanoramiXImageText8(ClientPtr client)
+{
+ int result, j;
+ PanoramiXWindow *pPanoramiXRoot;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int orig_x, orig_y;
+ REQUEST(xImageTextReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ pPanoramiXRoot = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXWin = pPanoramiXRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ if (pPanoramiXWin == pPanoramiXRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }else {
+ if ( (pDraw->type == DRAWABLE_PIXMAP) &&
+ /* special case root window bitmap */
+ (pDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*SavedProcVector[X_ImageText8])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXImageText16(ClientPtr client)
+{
+ int result, j;
+ PanoramiXWindow *pPanoramiXRoot;
+ PanoramiXWindow *pPanoramiXWin;
+ PanoramiXGC *pPanoramiXGC = PanoramiXGCRoot;
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int orig_x, orig_y;
+ REQUEST(xImageTextReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ pPanoramiXRoot = (pDraw->type == DRAWABLE_PIXMAP)
+ ? PanoramiXPmapRoot : PanoramiXWinRoot;
+ pPanoramiXWin = pPanoramiXRoot;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->drawable);
+ IF_RETURN(!pPanoramiXWin, BadDrawable);
+ PANORAMIXFIND_ID(pPanoramiXGC, stuff->gc);
+ IF_RETURN(!pPanoramiXGC, BadGC);
+ orig_x = stuff->x;
+ orig_y = stuff->y;
+ FOR_NSCREENS_OR_ONCE((pPanoramiXWin && pPanoramiXGC), j) {
+ stuff->drawable = pPanoramiXWin->info[j].id;
+ stuff->gc = pPanoramiXGC->info[j].id;
+ if (pPanoramiXWin == pPanoramiXRoot) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }else {
+ if ( (pDraw->type == DRAWABLE_PIXMAP) &&
+ /* special case root window bitmap */
+ (pDraw->width == (panoramiXdataPtr[PanoramiXNumScreens-1].x +
+ panoramiXdataPtr[PanoramiXNumScreens-1].width)) ) {
+ stuff->x = orig_x - panoramiXdataPtr[j].x;
+ stuff->y = orig_y - panoramiXdataPtr[j].y;
+ }
+ }
+ result = (*SavedProcVector[X_ImageText16])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXCreateColormap(register ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ register WindowPtr pWin;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+
+ REQUEST(xCreateColormapReq);
+
+ int i, result;
+ int vid_index, class_index;
+ int this_vid_index, this_class_index, this_depth;
+ int j = 0;
+ VisualID orig_visual;
+ Colormap cmapID;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXCmap *localCmap;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ short VisualClass;
+ Bool ClassKnown;
+ Bool FoundIt = FALSE;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ mid = stuff->mid;
+ orig_visual = stuff->visual;
+ j = 0;
+ PANORAMIXFIND_ID(pPanoramiXWin, stuff->window);
+ if (pPanoramiXWin) {
+ localCmap = (PanoramiXCmap *)Xcalloc(sizeof(PanoramiXCmap));
+ IF_RETURN(!localCmap, BadAlloc);
+ } else {
+ return BadWindow;
+ }
+ for (j = 0; j <= PanoramiXNumScreens - 1; j++) {
+ cmapID = j ? FakeClientID(client->index) : mid;
+ localCmap->info[j].id = cmapID;
+ }
+ localCmap->FreeMe = FALSE;
+ PANORAMIXFIND_LAST(pPanoramiXCmap, PanoramiXCmapRoot);
+ pPanoramiXCmap->next = localCmap;
+
+ /* Use Screen 0 to get the matching Visual ID */
+ pWin = (WindowPtr)SecurityLookupWindow(stuff->window, client,
+ SecurityReadAccess);
+ if ( stuff->visual != CopyFromParent)
+ {
+ /* Find the correct visual for screen 0 */
+ for (class_index = 0; class_index < PanoramiXColorDepthTable[0].numVisuals;
+class_index++)
+ {
+ for (j = 0; j < PanoramiXColorDepthTable[0].panoramiXScreenMap[class_index
+].numDepths; j++ )
+ {
+ pDepth = (DepthPtr) &pWin->drawable.pScreen->allowedDepths[j];
+ for (vid_index = 0; vid_index < PanoramiXColorDepthTable[0].panoramiXScreenMap[class_index].vmap[pDepth->depth].numVids; vid_index++)
+ {
+ if ( stuff->visual == PanoramiXColorDepthTable[0].panoramiXScreenMap[class_index].vmap[pDepth->depth].vid[vid_index] )
+ {
+ this_class_index = class_index;
+ this_vid_index = vid_index;
+ this_depth = pDepth->depth;
+ FoundIt = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (!pWin)
+ return(BadWindow);
+ pScreen = pWin->drawable.pScreen;
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin, j) {
+ stuff->mid = localCmap->info[j].id;
+ stuff->window = pPanoramiXWin->info[j].id;
+ /* Look for the matching visual class, and use its
+ visual id for creating this colormap. */
+ if ( orig_visual != CopyFromParent && FoundIt )
+ {
+ stuff->visual = PanoramiXColorDepthTable[j].panoramiXScreenMap[this_class_index].vmap[this_depth].vid[this_vid_index];
+ }
+ result = (* SavedProcVector[X_CreateColormap])(client);
+ BREAK_IF(result != Success);
+ }
+ if (result != Success) {
+ pPanoramiXCmap->next = NULL ;
+ if (localCmap)
+ Xfree(localCmap);
+ }
+ return (result);
+}
+
+
+int PanoramiXFreeColormap(ClientPtr client)
+{
+ ColormapPtr pmap;
+ REQUEST(xResourceReq);
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ PanoramiXCmap *pPanoramiXCmapback = NULL;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ for (; pPanoramiXCmap && (pPanoramiXCmap->info[0].id != stuff->id);
+ pPanoramiXCmap = pPanoramiXCmap->next)
+ pPanoramiXCmapback = pPanoramiXCmap;
+ IF_RETURN(!pPanoramiXCmap, BadColor);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->id = pPanoramiXCmap->info[j].id;
+ result = (* SavedProcVector[X_FreeColormap])(client);
+ BREAK_IF(result != Success);
+ }
+ if ((result == Success) && pPanoramiXCmapback &&
+ pPanoramiXCmap && pPanoramiXCmap->FreeMe) {
+ pPanoramiXCmapback->next = pPanoramiXCmap->next;
+ Xfree(pPanoramiXCmap);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXInstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->id);
+ IF_RETURN(!pPanoramiXCmap, BadColor);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->id = pPanoramiXCmap->info[j].id;
+ result = (* SavedProcVector[X_InstallColormap])(client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXUninstallColormap(register ClientPtr client)
+{
+ ColormapPtr pcmp;
+ REQUEST(xResourceReq);
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->id);
+ IF_RETURN(!pPanoramiXCmap, BadColor);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->id = pPanoramiXCmap->info[j].id;
+ result = (* SavedProcVector[X_UninstallColormap])(client);
+ BREAK_IF(result != Success);
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXAllocColor(ClientPtr client)
+{
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->cmap);
+ if (!pPanoramiXCmap){
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_AllocColor])(client);
+ noPanoramiXExtension = FALSE;
+ }else {
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->cmap = pPanoramiXCmap->info[j].id;
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_AllocColor])(client);
+ noPanoramiXExtension = FALSE;
+ BREAK_IF(result != Success);
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocNamedColor(ClientPtr client)
+{
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->cmap);
+ IF_RETURN(!pPanoramiXCmap, BadColor);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->cmap = pPanoramiXCmap->info[j].id;
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_AllocNamedColor])(client);
+ noPanoramiXExtension = FALSE;
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+
+
+int PanoramiXAllocColorCells(ClientPtr client)
+{
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->cmap);
+ if (!pPanoramiXCmap) {
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_AllocColorCells])(client);
+ noPanoramiXExtension = FALSE;
+ }else {
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->cmap = pPanoramiXCmap->info[j].id;
+ if (!j)
+ noPanoramiXExtension = TRUE;
+ result = (* SavedProcVector[X_AllocColorCells])(client);
+ noPanoramiXExtension = FALSE;
+ /* Because id's are eventually searched for in
+ some client list, we don't check for success
+ on fake id's last id will be real, we really
+ only care about results related to real id's
+ BREAK_IF(result != Success);
+ */
+ }
+ }
+ return (result);
+}
+
+
+int PanoramiXFreeColors(register ClientPtr client)
+{
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ REQUEST(xFreeColorsReq);
+
+ PanoramiXGC *pPanoramiXFreeGC;
+ PanoramiXGC *pPanoramiXFreeGCback = NULL;
+ PanoramiXWindow *pPanoramiXFreeWin;
+ PanoramiXWindow *pPanoramiXFreeWinback = NULL;
+ PanoramiXCmap *pPanoramiXFreeCmap;
+ PanoramiXCmap *pPanoramiXFreeCmapback = NULL;
+ PanoramiXPmap *pPanoramiXFreePmap;
+ PanoramiXPmap *pPanoramiXFreePmapback = NULL;
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->cmap);
+ IF_RETURN(!pPanoramiXCmap, BadColor);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->cmap = pPanoramiXCmap->info[j].id;
+ result = (* SavedProcVector[X_FreeColors])(client);
+ /* Because id's are eventually searched for in
+ some client list, we don't check for success
+ on fake id's last id will be real, we really
+ only care about results related to real id's */
+ }
+ PANORAMIX_FREE(client);
+ return (result);
+}
+
+
+int PanoramiXStoreColors(ClientPtr client)
+{
+ int result, j;
+ PanoramiXCmap *pPanoramiXCmap = PanoramiXCmapRoot;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ PANORAMIXFIND_ID(pPanoramiXCmap, stuff->cmap);
+ if (!pPanoramiXCmap)
+ result = (* SavedProcVector[X_StoreColors])(client);
+ else {
+ FOR_NSCREENS_OR_ONCE(pPanoramiXCmap, j) {
+ stuff->cmap = pPanoramiXCmap->info[j].id;
+ result = (* SavedProcVector[X_StoreColors])(client);
+ BREAK_IF(result != Success);
+ }
+ }
+ return (result);
+}
diff --git a/Xext/sampleEVI.c b/Xext/sampleEVI.c
new file mode 100644
index 000000000..43265a73d
--- /dev/null
+++ b/Xext/sampleEVI.c
@@ -0,0 +1,97 @@
+/* $Xorg: sampleEVI.c,v 1.3 2000/08/17 19:47:58 cpqbld Exp $ */
+/************************************************************
+Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
+Permission to use, copy, modify, and distribute this
+software and its documentation for any purpose and without
+fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright
+notice and this permission notice appear in supporting
+documentation, and that the name of Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
+THE USE OR PERFORMANCE OF THIS SOFTWARE.
+********************************************************/
+#include "X.h"
+#include "Xproto.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "dix.h"
+#define _XEVI_SERVER_
+#include "XEVIstr.h"
+#include "EVIstruct.h"
+#include "scrnintstr.h"
+static int sampleGetVisualInfo(
+ VisualID32 *visual,
+ int n_visual,
+ xExtendedVisualInfo **evi_rn,
+ int *n_info_rn,
+ VisualID32 **conflict_rn,
+ int *n_conflict_rn)
+{
+ int max_sz_evi = n_visual * sz_xExtendedVisualInfo * screenInfo.numScreens;
+ VisualID32 *temp_conflict;
+ xExtendedVisualInfo *evi;
+ int max_visuals = 0, max_sz_conflict, sz_conflict = 0;
+ register int visualI, scrI, sz_evi = 0, conflictI, n_conflict;
+ *evi_rn = evi = (xExtendedVisualInfo *)xalloc(max_sz_evi);
+ if (!*evi_rn)
+ return BadAlloc;
+ for (scrI = 0; scrI < screenInfo.numScreens; scrI++) {
+ if (screenInfo.screens[scrI]->numVisuals > max_visuals)
+ max_visuals = screenInfo.screens[scrI]->numVisuals;
+ }
+ max_sz_conflict = n_visual * sz_VisualID32 * screenInfo.numScreens * max_visuals;
+ temp_conflict = (VisualID32 *)xalloc(max_sz_conflict);
+ if (!temp_conflict) {
+ xfree(*evi_rn);
+ return BadAlloc;
+ }
+ for (scrI = 0; scrI < screenInfo.numScreens; scrI++) {
+ for (visualI = 0; visualI < n_visual; visualI++) {
+ evi[sz_evi].core_visual_id = visual[visualI];
+ evi[sz_evi].screen = scrI;
+ evi[sz_evi].level = 0;
+ evi[sz_evi].transparency_type = XEVI_TRANSPARENCY_NONE;
+ evi[sz_evi].transparency_value = 0;
+ evi[sz_evi].min_hw_colormaps = 1;
+ evi[sz_evi].max_hw_colormaps = 1;
+ evi[sz_evi].num_colormap_conflicts = n_conflict = 0;
+ for (conflictI = 0; conflictI < n_conflict; conflictI++)
+ temp_conflict[sz_conflict++] = visual[visualI];
+ sz_evi++;
+ }
+ }
+ *conflict_rn = temp_conflict;
+ *n_conflict_rn = sz_conflict;
+ *n_info_rn = sz_evi;
+ return Success;
+}
+static void sampleFreeVisualInfo(
+ xExtendedVisualInfo *evi,
+ VisualID32 *conflict)
+{
+ if (evi)
+ xfree(evi);
+ if (conflict)
+ xfree(conflict);
+}
+EviPrivPtr eviDDXInit()
+{
+ static EviPrivRec eviPriv;
+ eviPriv.getVisualInfo = sampleGetVisualInfo;
+ eviPriv.freeVisualInfo = sampleFreeVisualInfo;
+ return &eviPriv;
+}
+void eviDDXReset()
+{
+}
diff --git a/Xext/security.c b/Xext/security.c
new file mode 100644
index 000000000..c2db8f4dd
--- /dev/null
+++ b/Xext/security.c
@@ -0,0 +1,1995 @@
+/* $Xorg: security.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+/*
+
+Copyright 1996, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include "gcstruct.h"
+#include "colormapst.h"
+#include "propertyst.h"
+#define _SECURITY_SERVER
+#include "securstr.h"
+#include <assert.h>
+#include <stdarg.h>
+#ifdef LBX
+#define _XLBX_SERVER_
+#include "XLbx.h"
+extern unsigned char LbxReqCode;
+#endif
+#ifdef XAPPGROUP
+#include "Xagsrv.h"
+#endif
+#include <stdio.h> /* for file reading operations */
+#include "Xatom.h" /* for XA_STRING */
+
+#ifndef DEFAULTPOLICYFILE
+# define DEFAULTPOLICYFILE NULL
+#endif
+#ifdef WIN32
+#include <X11/Xos.h>
+#undef index
+#endif
+
+static int SecurityErrorBase; /* first Security error number */
+static int SecurityEventBase; /* first Security event number */
+
+CallbackListPtr SecurityValidateGroupCallback = NULL; /* see security.h */
+
+RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */
+
+static RESTYPE RTEventClient;
+
+/* Proc vectors for untrusted clients, swapped and unswapped versions.
+ * These are the same as the normal proc vectors except that extensions
+ * that haven't declared themselves secure will have ProcBadRequest plugged
+ * in for their major opcode dispatcher. This prevents untrusted clients
+ * from guessing extension major opcodes and using the extension even though
+ * the extension can't be listed or queried.
+ */
+int (*UntrustedProcVector[256])(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+int (*SwappedUntrustedProcVector[256])(
+#if NeedNestedPrototypes
+ ClientPtr /*client*/
+#endif
+);
+
+extern int ProcBadRequest();
+
+
+/* SecurityAudit
+ *
+ * Arguments:
+ * format is the formatting string to be used to interpret the
+ * remaining arguments.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Writes the message to the log file if security logging is on.
+ */
+
+void
+SecurityAudit(char *format, ...)
+{
+ va_list args;
+
+ if (auditTrailLevel < SECURITY_AUDIT_LEVEL)
+ return;
+ AuditPrefix(format);
+ va_start(args, format);
+ VErrorF(format, args);
+ va_end(args);
+} /* SecurityAudit */
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+/* SecurityDeleteAuthorization
+ *
+ * Arguments:
+ * value is the authorization to delete.
+ * id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ * Frees everything associated with the authorization.
+ */
+
+static int
+SecurityDeleteAuthorization(value, id)
+ pointer value;
+ XID id;
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+ unsigned short name_len, data_len;
+ char *name, *data;
+ int status;
+ int i;
+ OtherClientsPtr pEventClient;
+
+ /* Remove the auth using the os layer auth manager */
+
+ status = AuthorizationFromID(pAuth->id, &name_len, &name,
+ &data_len, &data);
+ assert(status);
+ status = RemoveAuthorization(name_len, name, data_len, data);
+ assert(status);
+
+ /* free the auth timer if there is one */
+
+ if (pAuth->timer) TimerFree(pAuth->timer);
+
+ /* send revoke events */
+
+ while (pEventClient = pAuth->eventClients)
+ {
+ /* send revocation event event */
+ ClientPtr client = rClient(pEventClient);
+
+ if (!client->clientGone)
+ {
+ xSecurityAuthorizationRevokedEvent are;
+ are.type = SecurityEventBase + XSecurityAuthorizationRevoked;
+ are.sequenceNumber = client->sequence;
+ are.authId = pAuth->id;
+ WriteEventsToClient(client, 1, (xEvent *)&are);
+ }
+ FreeResource(pEventClient->resource, RT_NONE);
+ }
+
+ /* kill all clients using this auth */
+
+ for (i = 1; i<currentMaxClients; i++)
+ {
+ if (clients[i] && (clients[i]->authId == pAuth->id))
+ CloseDownClient(clients[i]);
+ }
+
+ SecurityAudit("revoked authorization ID %d\n", pAuth->id);
+ xfree(pAuth);
+ return Success;
+
+} /* SecurityDeleteAuthorization */
+
+
+/* resource delete function for RTEventClient */
+static int
+SecurityDeleteAuthorizationEventClient(value, id)
+ pointer value;
+ XID id;
+{
+ OtherClientsPtr pEventClient, prev = NULL;
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (pEventClient->resource == id)
+ {
+ if (prev)
+ prev->next = pEventClient->next;
+ else
+ pAuth->eventClients = pEventClient->next;
+ xfree(pEventClient);
+ return(Success);
+ }
+ prev = pEventClient;
+ }
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+} /* SecurityDeleteAuthorizationEventClient */
+
+
+/* SecurityComputeAuthorizationTimeout
+ *
+ * Arguments:
+ * pAuth is the authorization for which we are computing the timeout
+ * seconds is the number of seconds we want to wait
+ *
+ * Returns:
+ * the number of milliseconds that the auth timer should be set to
+ *
+ * Side Effects:
+ * Sets pAuth->secondsRemaining to any "overflow" amount of time
+ * that didn't fit in 32 bits worth of milliseconds
+ */
+
+static CARD32
+SecurityComputeAuthorizationTimeout(pAuth, seconds)
+ SecurityAuthorizationPtr pAuth;
+ unsigned int seconds;
+{
+ /* maxSecs is the number of full seconds that can be expressed in
+ * 32 bits worth of milliseconds
+ */
+ CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND;
+
+ if (seconds > maxSecs)
+ { /* only come here if we want to wait more than 49 days */
+ pAuth->secondsRemaining = seconds - maxSecs;
+ return maxSecs * MILLI_PER_SECOND;
+ }
+ else
+ { /* by far the common case */
+ pAuth->secondsRemaining = 0;
+ return seconds * MILLI_PER_SECOND;
+ }
+} /* SecurityStartAuthorizationTimer */
+
+/* SecurityAuthorizationExpired
+ *
+ * This function is passed as an argument to TimerSet and gets called from
+ * the timer manager in the os layer when its time is up.
+ *
+ * Arguments:
+ * timer is the timer for this authorization.
+ * time is the current time.
+ * pval is the authorization whose time is up.
+ *
+ * Returns:
+ * A new time delay in milliseconds if the timer should wait some
+ * more, else zero.
+ *
+ * Side Effects:
+ * Frees the authorization resource if the timeout period is really
+ * over, otherwise recomputes pAuth->secondsRemaining.
+ */
+
+static CARD32
+SecurityAuthorizationExpired(timer, time, pval)
+ OsTimerPtr timer;
+ CARD32 time;
+ pointer pval;
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval;
+
+ assert(pAuth->timer == timer);
+
+ if (pAuth->secondsRemaining)
+ {
+ return SecurityComputeAuthorizationTimeout(pAuth,
+ pAuth->secondsRemaining);
+ }
+ else
+ {
+ FreeResource(pAuth->id, RT_NONE);
+ return 0;
+ }
+} /* SecurityAuthorizationExpired */
+
+/* SecurityStartAuthorizationTimer
+ *
+ * Arguments:
+ * pAuth is the authorization whose timer should be started.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * A timer is started, set to expire after the timeout period for
+ * this authorization. When it expires, the function
+ * SecurityAuthorizationExpired will be called.
+ */
+
+static void
+SecurityStartAuthorizationTimer(pAuth)
+ SecurityAuthorizationPtr pAuth;
+{
+ pAuth->timer = TimerSet(pAuth->timer, 0,
+ SecurityComputeAuthorizationTimeout(pAuth, pAuth->timeout),
+ SecurityAuthorizationExpired, pAuth);
+} /* SecurityStartAuthorizationTimer */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcSecurityQueryVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityQueryVersionReq);
+ xSecurityQueryVersionReply rep;
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = SECURITY_MAJOR_VERSION;
+ rep.minorVersion = SECURITY_MINOR_VERSION;
+ if(client->swapped)
+ {
+ register char n;
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ (void)WriteToClient(client, SIZEOF(xSecurityQueryVersionReply),
+ (char *)&rep);
+ return (client->noClientException);
+} /* ProcSecurityQueryVersion */
+
+
+static int
+SecurityEventSelectForAuthorization(pAuth, client, mask)
+ SecurityAuthorizationPtr pAuth;
+ ClientPtr client;
+ Mask mask;
+{
+ OtherClients *pEventClient;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (SameClient(pEventClient, client))
+ {
+ if (mask == 0)
+ FreeResource(pEventClient->resource, RT_NONE);
+ else
+ pEventClient->mask = mask;
+ return Success;
+ }
+ }
+
+ pEventClient = (OtherClients *) xalloc(sizeof(OtherClients));
+ if (!pEventClient)
+ return BadAlloc;
+ pEventClient->mask = mask;
+ pEventClient->resource = FakeClientID(client->index);
+ pEventClient->next = pAuth->eventClients;
+ if (!AddResource(pEventClient->resource, RTEventClient,
+ (pointer)pAuth))
+ {
+ xfree(pEventClient);
+ return BadAlloc;
+ }
+ pAuth->eventClients = pEventClient;
+
+ return Success;
+} /* SecurityEventSelectForAuthorization */
+
+
+static int
+ProcSecurityGenerateAuthorization(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ int len; /* request length in CARD32s*/
+ Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */
+ SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */
+ int err; /* error to return from this function */
+ int status; /* return value from os functions */
+ XID authId; /* authorization ID assigned by os layer */
+ xSecurityGenerateAuthorizationReply rep; /* reply struct */
+ unsigned int trustLevel; /* trust level of new auth */
+ XID group; /* group of new auth */
+ CARD32 timeout; /* timeout of new auth */
+ CARD32 *values; /* list of supplied attributes */
+ char *protoname; /* auth proto name sent in request */
+ char *protodata; /* auth proto data sent in request */
+ unsigned int authdata_len; /* # bytes of generated auth data */
+ char *pAuthdata; /* generated auth data */
+ Mask eventMask; /* what events on this auth does client want */
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ /* check request length */
+
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ len = SIZEOF(xSecurityGenerateAuthorizationReq) >> 2;
+ len += (stuff->nbytesAuthProto + (unsigned)3) >> 2;
+ len += (stuff->nbytesAuthData + (unsigned)3) >> 2;
+ values = ((CARD32 *)stuff) + len;
+ len += Ones(stuff->valueMask);
+ if (client->req_len != len)
+ return BadLength;
+
+ /* check valuemask */
+ if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes)
+ {
+ client->errorValue = stuff->valueMask;
+ return BadValue;
+ }
+
+ /* check timeout */
+ timeout = 60;
+ if (stuff->valueMask & XSecurityTimeout)
+ {
+ timeout = *values++;
+ }
+
+ /* check trustLevel */
+ trustLevel = XSecurityClientUntrusted;
+ if (stuff->valueMask & XSecurityTrustLevel)
+ {
+ trustLevel = *values++;
+ if (trustLevel != XSecurityClientTrusted &&
+ trustLevel != XSecurityClientUntrusted)
+ {
+ client->errorValue = trustLevel;
+ return BadValue;
+ }
+ }
+
+ /* check group */
+ group = None;
+ if (stuff->valueMask & XSecurityGroup)
+ {
+ group = *values++;
+ if (SecurityValidateGroupCallback)
+ {
+ SecurityValidateGroupInfoRec vgi;
+ vgi.group = group;
+ vgi.valid = FALSE;
+ CallCallbacks(&SecurityValidateGroupCallback, (pointer)&vgi);
+
+ /* if nobody said they recognized it, it's an error */
+
+ if (!vgi.valid)
+ {
+ client->errorValue = group;
+ return BadValue;
+ }
+ }
+ }
+
+ /* check event mask */
+ eventMask = 0;
+ if (stuff->valueMask & XSecurityEventMask)
+ {
+ eventMask = *values++;
+ if (eventMask & ~XSecurityAllEventMasks)
+ {
+ client->errorValue = eventMask;
+ return BadValue;
+ }
+ }
+
+ protoname = (char *)&stuff[1];
+ protodata = protoname + ((stuff->nbytesAuthProto + (unsigned)3) >> 2);
+
+ /* call os layer to generate the authorization */
+
+ authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname,
+ stuff->nbytesAuthData, protodata,
+ &authdata_len, &pAuthdata);
+ if ((XID) ~0L == authId)
+ {
+ err = SecurityErrorBase + XSecurityBadAuthorizationProtocol;
+ goto bailout;
+ }
+
+ /* now that we've added the auth, remember to remove it if we have to
+ * abort the request for some reason (like allocation failure)
+ */
+ removeAuth = TRUE;
+
+ /* associate additional information with this auth ID */
+
+ pAuth = (SecurityAuthorizationPtr)xalloc(sizeof(SecurityAuthorizationRec));
+ if (!pAuth)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* fill in the auth fields */
+
+ pAuth->id = authId;
+ pAuth->timeout = timeout;
+ pAuth->group = group;
+ pAuth->trustLevel = trustLevel;
+ pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */
+ pAuth->secondsRemaining = 0;
+ pAuth->timer = NULL;
+ pAuth->eventClients = NULL;
+
+ /* handle event selection */
+ if (eventMask)
+ {
+ err = SecurityEventSelectForAuthorization(pAuth, client, eventMask);
+ if (err != Success)
+ goto bailout;
+ }
+
+ if (!AddResource(authId, SecurityAuthorizationResType, pAuth))
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* start the timer ticking */
+
+ if (pAuth->timeout != 0)
+ SecurityStartAuthorizationTimer(pAuth);
+
+ /* tell client the auth id and data */
+
+ rep.type = X_Reply;
+ rep.length = (authdata_len + 3) >> 2;
+ rep.sequenceNumber = client->sequence;
+ rep.authId = authId;
+ rep.dataLength = authdata_len;
+
+ if (client->swapped)
+ {
+ register char n;
+ swapl(&rep.length, n);
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.authId, n);
+ swaps(&rep.dataLength, n);
+ }
+
+ WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply),
+ (char *)&rep);
+ WriteToClient(client, authdata_len, pAuthdata);
+
+ SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n",
+ client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout,
+ pAuth->group, eventMask);
+
+ /* the request succeeded; don't call RemoveAuthorization or free pAuth */
+
+ removeAuth = FALSE;
+ pAuth = NULL;
+ err = client->noClientException;
+
+bailout:
+ if (removeAuth)
+ RemoveAuthorization(stuff->nbytesAuthProto, protoname,
+ authdata_len, pAuthdata);
+ if (pAuth) xfree(pAuth);
+ return err;
+
+} /* ProcSecurityGenerateAuthorization */
+
+static int
+ProcSecurityRevokeAuthorization(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+ SecurityAuthorizationPtr pAuth;
+
+ /* paranoia: this "can't happen" because this extension is hidden
+ * from untrusted clients, but just in case...
+ */
+ if (client->trustLevel != XSecurityClientTrusted)
+ return BadRequest;
+
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+
+ pAuth = (SecurityAuthorizationPtr)SecurityLookupIDByType(client,
+ stuff->authId, SecurityAuthorizationResType, SecurityDestroyAccess);
+ if (!pAuth)
+ return SecurityErrorBase + XSecurityBadAuthorization;
+
+ FreeResource(stuff->authId, RT_NONE);
+ return Success;
+} /* ProcSecurityRevokeAuthorization */
+
+
+static int
+ProcSecurityDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return ProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return ProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return ProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* ProcSecurityDispatch */
+
+static int
+SProcSecurityQueryVersion(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityQueryVersionReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ swaps(&stuff->majorVersion, n);
+ swaps(&stuff->minorVersion,n);
+ return ProcSecurityQueryVersion(client);
+} /* SProcSecurityQueryVersion */
+
+
+static int
+SProcSecurityGenerateAuthorization(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ register char n;
+ CARD32 *values;
+ unsigned long nvalues;
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ swaps(&stuff->nbytesAuthProto, n);
+ swaps(&stuff->nbytesAuthData, n);
+ swapl(&stuff->valueMask, n);
+ values = (CARD32 *)(&stuff[1]) +
+ ((stuff->nbytesAuthProto + (unsigned)3) >> 2) +
+ ((stuff->nbytesAuthData + (unsigned)3) >> 2);
+ nvalues = (((CARD32 *)stuff) + stuff->length) - values;
+ SwapLongs(values, nvalues);
+ return ProcSecurityGenerateAuthorization(client);
+} /* SProcSecurityGenerateAuthorization */
+
+
+static int
+SProcSecurityRevokeAuthorization(client)
+ ClientPtr client;
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+ register char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+ swapl(&stuff->authId, n);
+ return ProcSecurityRevokeAuthorization(client);
+} /* SProcSecurityRevokeAuthorization */
+
+
+static int
+SProcSecurityDispatch(client)
+ ClientPtr client;
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return SProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return SProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return SProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* SProcSecurityDispatch */
+
+static void
+SwapSecurityAuthorizationRevokedEvent(from, to)
+ xSecurityAuthorizationRevokedEvent *from, *to;
+{
+ to->type = from->type;
+ to->detail = from->detail;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->authId, to->authId);
+}
+
+/* SecurityDetermineEventPropogationLimits
+ *
+ * This is a helper function for SecurityCheckDeviceAccess.
+ *
+ * Arguments:
+ * dev is the device for which the starting and stopping windows for
+ * event propogation should be determined.
+ * The values pointed to by ppWin and ppStopWin are not used.
+ *
+ * Returns:
+ * ppWin is filled in with a pointer to the window at which event
+ * propogation for the given device should start given the current
+ * state of the server (pointer position, window layout, etc.)
+ * ppStopWin is filled in with the window at which event propogation
+ * should stop; events should not go to ppStopWin.
+ *
+ * Side Effects: none.
+ */
+
+static void
+SecurityDetermineEventPropogationLimits(dev, ppWin, ppStopWin)
+ DeviceIntPtr dev;
+ WindowPtr *ppWin;
+ WindowPtr *ppStopWin;
+{
+ WindowPtr pFocusWin = dev->focus ? dev->focus->win : NoneWin;
+
+ if (pFocusWin == NoneWin)
+ { /* no focus -- events don't go anywhere */
+ *ppWin = *ppStopWin = NULL;
+ return;
+ }
+
+ if (pFocusWin == PointerRootWin)
+ { /* focus follows the pointer */
+ *ppWin = GetSpriteWindow();
+ *ppStopWin = NULL; /* propogate all the way to the root */
+ }
+ else
+ { /* a real window is set for the focus */
+ WindowPtr pSpriteWin = GetSpriteWindow();
+ *ppStopWin = pFocusWin->parent; /* don't go past the focus window */
+
+ /* if the pointer is in a subwindow of the focus window, start
+ * at that subwindow, else start at the focus window itself
+ */
+ if (IsParent(pFocusWin, pSpriteWin))
+ *ppWin = pSpriteWin;
+ else *ppWin = pFocusWin;
+ }
+} /* SecurityDetermineEventPropogationLimits */
+
+
+/* SecurityCheckDeviceAccess
+ *
+ * Arguments:
+ * client is the client attempting to access a device.
+ * dev is the device being accessed.
+ * fromRequest is TRUE if the device access is a direct result of
+ * the client executing some request and FALSE if it is a
+ * result of the server trying to send an event (e.g. KeymapNotify)
+ * to the client.
+ * Returns:
+ * TRUE if the device access should be allowed, else FALSE.
+ *
+ * Side Effects:
+ * An audit message is generated if access is denied.
+ */
+
+Bool
+SecurityCheckDeviceAccess(client, dev, fromRequest)
+ ClientPtr client;
+ DeviceIntPtr dev;
+ Bool fromRequest;
+{
+ WindowPtr pWin, pStopWin;
+ Bool untrusted_got_event;
+ Bool found_event_window;
+ Mask eventmask;
+ int reqtype;
+
+ /* trusted clients always allowed to do anything */
+ if (client->trustLevel == XSecurityClientTrusted)
+ return TRUE;
+
+ /* device security other than keyboard is not implemented yet */
+ if (dev != inputInfo.keyboard)
+ return TRUE;
+
+ /* some untrusted client wants access */
+
+ if (fromRequest)
+ {
+ reqtype = ((xReq *)client->requestBuffer)->reqType;
+ switch (reqtype)
+ {
+ /* never allow these */
+ case X_ChangeKeyboardMapping:
+ case X_ChangeKeyboardControl:
+ case X_SetModifierMapping:
+ SecurityAudit("client %d attempted request %d\n",
+ client->index, reqtype);
+ return FALSE;
+ default:
+ break;
+ }
+ }
+
+ untrusted_got_event = FALSE;
+ found_event_window = FALSE;
+
+ if (dev->grab)
+ {
+ untrusted_got_event =
+ ((rClient(dev->grab))->trustLevel != XSecurityClientTrusted);
+ }
+ else
+ {
+ SecurityDetermineEventPropogationLimits(dev, &pWin, &pStopWin);
+
+ eventmask = KeyPressMask | KeyReleaseMask;
+ while ( (pWin != pStopWin) && !found_event_window)
+ {
+ OtherClients *other;
+
+ if (pWin->eventMask & eventmask)
+ {
+ found_event_window = TRUE;
+ client = wClient(pWin);
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ untrusted_got_event = TRUE;
+ }
+ }
+ if (wOtherEventMasks(pWin) & eventmask)
+ {
+ found_event_window = TRUE;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & eventmask)
+ {
+ client = rClient(other);
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ untrusted_got_event = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (wDontPropagateMask(pWin) & eventmask)
+ break;
+ pWin = pWin->parent;
+ } /* while propogating the event */
+ }
+
+ /* allow access by untrusted clients only if an event would have gone
+ * to an untrusted client
+ */
+
+ if (!untrusted_got_event)
+ {
+ char *devname = dev->name;
+ if (!devname) devname = "unnamed";
+ if (fromRequest)
+ SecurityAudit("client %d attempted request %d device %d (%s)\n",
+ client->index, reqtype, dev->id, devname);
+ else
+ SecurityAudit("client %d attempted to access device %d (%s)\n",
+ client->index, dev->id, devname);
+ }
+ return untrusted_got_event;
+} /* SecurityCheckDeviceAccess */
+
+
+
+/* SecurityAuditResourceIDAccess
+ *
+ * Arguments:
+ * client is the client doing the resource access.
+ * id is the resource id.
+ *
+ * Returns: NULL
+ *
+ * Side Effects:
+ * An audit message is generated with details of the denied
+ * resource access.
+ */
+
+static pointer
+SecurityAuditResourceIDAccess(client, id)
+ ClientPtr client;
+ XID id;
+{
+ int cid = CLIENT_ID(id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+ switch (reqtype)
+ {
+ case X_ChangeProperty:
+ case X_DeleteProperty:
+ case X_GetProperty:
+ {
+ xChangePropertyReq *req =
+ (xChangePropertyReq *)client->requestBuffer;
+ int propertyatom = req->property;
+ char *propertyname = NameForAtom(propertyatom);
+
+ SecurityAudit("client %d attempted request %d with window 0x%x property %s of client %d\n",
+ client->index, reqtype, id, propertyname, cid);
+ break;
+ }
+ default:
+ {
+ SecurityAudit("client %d attempted request %d with resource 0x%x of client %d\n",
+ client->index, reqtype, id, cid);
+ break;
+ }
+ }
+ return NULL;
+} /* SecurityAuditResourceIDAccess */
+
+
+/* SecurityCheckResourceIDAccess
+ *
+ * This function gets plugged into client->CheckAccess and is called from
+ * SecurityLookupIDByType/Class to determine if the client can access the
+ * resource.
+ *
+ * Arguments:
+ * client is the client doing the resource access.
+ * id is the resource id.
+ * rtype is its type or class.
+ * access_mode represents the intended use of the resource; see
+ * resource.h.
+ * rval is a pointer to the resource structure for this resource.
+ *
+ * Returns:
+ * If access is granted, the value of rval that was passed in, else NULL.
+ *
+ * Side Effects:
+ * Disallowed resource accesses are audited.
+ */
+
+static pointer
+SecurityCheckResourceIDAccess(client, id, rtype, access_mode, rval)
+ ClientPtr client;
+ XID id;
+ RESTYPE rtype;
+ Mask access_mode;
+ pointer rval;
+{
+ int cid = CLIENT_ID(id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+
+ if (SecurityUnknownAccess == access_mode)
+ return rval; /* for compatibility, we have to allow access */
+
+ switch (reqtype)
+ { /* these are always allowed */
+ case X_QueryTree:
+ case X_TranslateCoords:
+ case X_GetGeometry:
+ /* property access is controlled in SecurityCheckPropertyAccess */
+ case X_GetProperty:
+ case X_ChangeProperty:
+ case X_DeleteProperty:
+ case X_RotateProperties:
+ case X_ListProperties:
+ return rval;
+ default:
+ break;
+ }
+
+ if (cid != 0)
+ { /* not a server-owned resource */
+ /*
+ * The following 'if' restricts clients to only access resources at
+ * the same trustLevel. Since there are currently only two trust levels,
+ * and trusted clients never call this function, this degenerates into
+ * saying that untrusted clients can only access resources of other
+ * untrusted clients. One way to add the notion of groups would be to
+ * allow values other than Trusted (0) and Untrusted (1) for this field.
+ * Clients at the same trust level would be able to use each other's
+ * resources, but not those of clients at other trust levels. I haven't
+ * tried it, but this probably mostly works already. The obvious
+ * competing alternative for grouping clients for security purposes is to
+ * use app groups. dpw
+ */
+ if (client->trustLevel == clients[cid]->trustLevel
+#ifdef XAPPGROUP
+ || (RT_COLORMAP == rtype &&
+ XagDefaultColormap (client) == (Colormap) id)
+#endif
+ )
+ return rval;
+ else
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ else /* server-owned resource - probably a default colormap or root window */
+ {
+ if (RT_WINDOW == rtype || RC_DRAWABLE == rtype)
+ {
+ switch (reqtype)
+ { /* the following operations are allowed on root windows */
+ case X_CreatePixmap:
+ case X_CreateGC:
+ case X_CreateWindow:
+ case X_CreateColormap:
+ case X_ListProperties:
+ case X_GrabPointer:
+ case X_UngrabButton:
+ case X_QueryBestSize:
+ case X_GetWindowAttributes:
+ break;
+ case X_SendEvent:
+ { /* see if it is an event specified by the ICCCM */
+ xSendEventReq *req = (xSendEventReq *)
+ (client->requestBuffer);
+ if (req->propagate == xTrue
+ ||
+ (req->eventMask != ColormapChangeMask &&
+ req->eventMask != StructureNotifyMask &&
+ req->eventMask !=
+ (SubstructureRedirectMask|SubstructureNotifyMask)
+ )
+ ||
+ (req->event.u.u.type != UnmapNotify &&
+ req->event.u.u.type != ConfigureRequest &&
+ req->event.u.u.type != ClientMessage
+ )
+ )
+ { /* not an ICCCM event */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ break;
+ } /* case X_SendEvent on root */
+
+ case X_ChangeWindowAttributes:
+ { /* Allow selection of PropertyNotify and StructureNotify
+ * events on the root.
+ */
+ xChangeWindowAttributesReq *req =
+ (xChangeWindowAttributesReq *)(client->requestBuffer);
+ if (req->valueMask == CWEventMask)
+ {
+ CARD32 value = *((CARD32 *)(req + 1));
+ if ( (value &
+ ~(PropertyChangeMask|StructureNotifyMask)) == 0)
+ break;
+ }
+ return SecurityAuditResourceIDAccess(client, id);
+ } /* case X_ChangeWindowAttributes on root */
+
+ default:
+ {
+#ifdef LBX
+ /* XXX really need per extension dispatching */
+ if (reqtype == LbxReqCode) {
+ switch (((xReq *)client->requestBuffer)->data) {
+ case X_LbxGetProperty:
+ case X_LbxChangeProperty:
+ return rval;
+ default:
+ break;
+ }
+ }
+#endif
+ /* others not allowed */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ }
+ } /* end server-owned window or drawable */
+ else if (SecurityAuthorizationResType == rtype)
+ {
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)rval;
+ if (pAuth->trustLevel != client->trustLevel)
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ else if (RT_COLORMAP != rtype)
+ { /* don't allow anything else besides colormaps */
+ return SecurityAuditResourceIDAccess(client, id);
+ }
+ }
+ return rval;
+} /* SecurityCheckResourceIDAccess */
+
+
+/* SecurityClientStateCallback
+ *
+ * Arguments:
+ * pcbl is &ClientStateCallback.
+ * nullata is NULL.
+ * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ * which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *
+ * If a new client is connecting, its authorization ID is copied to
+ * client->authID. If this is a generated authorization, its reference
+ * count is bumped, its timer is cancelled if it was running, and its
+ * trustlevel is copied to client->trustLevel.
+ *
+ * If a client is disconnecting and the client was using a generated
+ * authorization, the authorization's reference count is decremented, and
+ * if it is now zero, the timer for this authorization is started.
+ */
+
+static void
+SecurityClientStateCallback(pcbl, nulldata, calldata)
+ CallbackListPtr *pcbl;
+ pointer nulldata;
+ pointer calldata;
+{
+ NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
+ ClientPtr client = pci->client;
+
+ switch (client->clientState)
+ {
+ case ClientStateRunning:
+ {
+ XID authId = AuthorizationIDOfClient(client);
+ SecurityAuthorizationPtr pAuth;
+
+ client->authId = authId;
+ pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
+ SecurityAuthorizationResType);
+ if (pAuth)
+ { /* it is a generated authorization */
+ pAuth->refcnt++;
+ if (pAuth->refcnt == 1)
+ {
+ if (pAuth->timer) TimerCancel(pAuth->timer);
+ }
+ client->trustLevel = pAuth->trustLevel;
+ if (client->trustLevel != XSecurityClientTrusted)
+ {
+ client->CheckAccess = SecurityCheckResourceIDAccess;
+ client->requestVector = client->swapped ?
+ SwappedUntrustedProcVector : UntrustedProcVector;
+ }
+ }
+ break;
+ }
+ case ClientStateGone:
+ case ClientStateRetained: /* client disconnected */
+ {
+ XID authId = client->authId;
+ SecurityAuthorizationPtr pAuth;
+
+ pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
+ SecurityAuthorizationResType);
+ if (pAuth)
+ { /* it is a generated authorization */
+ pAuth->refcnt--;
+ if (pAuth->refcnt == 0)
+ {
+ SecurityStartAuthorizationTimer(pAuth);
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+} /* SecurityClientStateCallback */
+
+#ifdef LBX
+Bool
+SecuritySameLevel(client, authId)
+ ClientPtr client;
+ XID authId;
+{
+ SecurityAuthorizationPtr pAuth;
+
+ pAuth = (SecurityAuthorizationPtr)LookupIDByType(authId,
+ SecurityAuthorizationResType);
+ if (pAuth)
+ return client->trustLevel == pAuth->trustLevel;
+ return client->trustLevel == XSecurityClientTrusted;
+}
+#endif
+
+/* SecurityCensorImage
+ *
+ * Called after pScreen->GetImage to prevent pieces or trusted windows from
+ * being returned in image data from an untrusted window.
+ *
+ * Arguments:
+ * client is the client doing the GetImage.
+ * pVisibleRegion is the visible region of the window.
+ * widthBytesLine is the width in bytes of one horizontal line in pBuf.
+ * pDraw is the source window.
+ * x, y, w, h is the rectangle of image data from pDraw in pBuf.
+ * format is the format of the image data in pBuf: ZPixmap or XYPixmap.
+ * pBuf is the image data.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Any part of the rectangle (x, y, w, h) that is outside the visible
+ * region of the window will be destroyed (overwritten) in pBuf.
+ */
+void
+SecurityCensorImage(client, pVisibleRegion, widthBytesLine, pDraw, x, y, w, h,
+ format, pBuf)
+ ClientPtr client;
+ RegionPtr pVisibleRegion;
+ long widthBytesLine;
+ DrawablePtr pDraw;
+ int x, y, w, h;
+ unsigned int format;
+ char * pBuf;
+{
+ RegionRec imageRegion; /* region representing x,y,w,h */
+ RegionRec censorRegion; /* region to obliterate */
+ BoxRec imageBox;
+ int nRects;
+
+ imageBox.x1 = x;
+ imageBox.y1 = y;
+ imageBox.x2 = x + w;
+ imageBox.y2 = y + h;
+ REGION_INIT(pScreen, &imageRegion, &imageBox, 1);
+ REGION_INIT(pScreen, &censorRegion, NullBox, 0);
+
+ /* censorRegion = imageRegion - visibleRegion */
+ REGION_SUBTRACT(pScreen, &censorRegion, &imageRegion, pVisibleRegion);
+ nRects = REGION_NUM_RECTS(&censorRegion);
+ if (nRects > 0)
+ { /* we have something to censor */
+ GCPtr pScratchGC = NULL;
+ PixmapPtr pPix = NULL;
+ xRectangle *pRects = NULL;
+ Bool failed = FALSE;
+ int depth = 1;
+ int bitsPerPixel = 1;
+ int i;
+ BoxPtr pBox;
+
+ /* convert region to list-of-rectangles for PolyFillRect */
+
+ pRects = (xRectangle *)ALLOCATE_LOCAL(nRects * sizeof(xRectangle *));
+ if (!pRects)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+ for (pBox = REGION_RECTS(&censorRegion), i = 0;
+ i < nRects;
+ i++, pBox++)
+ {
+ pRects[i].x = pBox->x1;
+ pRects[i].y = pBox->y1 - imageBox.y1;
+ pRects[i].width = pBox->x2 - pBox->x1;
+ pRects[i].height = pBox->y2 - pBox->y1;
+ }
+
+ /* use pBuf as a fake pixmap */
+
+ if (format == ZPixmap)
+ {
+ depth = pDraw->depth;
+ bitsPerPixel = pDraw->bitsPerPixel;
+ }
+
+ pPix = GetScratchPixmapHeader(pDraw->pScreen, w, h,
+ depth, bitsPerPixel,
+ widthBytesLine, (pointer)pBuf);
+ if (!pPix)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+
+ pScratchGC = GetScratchGC(depth, pPix->drawable.pScreen);
+ if (!pScratchGC)
+ {
+ failed = TRUE;
+ goto failSafe;
+ }
+
+ ValidateGC(&pPix->drawable, pScratchGC);
+ (* pScratchGC->ops->PolyFillRect)(&pPix->drawable,
+ pScratchGC, nRects, pRects);
+
+ failSafe:
+ if (failed)
+ {
+ /* Censoring was not completed above. To be safe, wipe out
+ * all the image data so that nothing trusted gets out.
+ */
+ bzero(pBuf, (int)(widthBytesLine * h));
+ }
+ if (pRects) DEALLOCATE_LOCAL(pRects);
+ if (pScratchGC) FreeScratchGC(pScratchGC);
+ if (pPix) FreeScratchPixmapHeader(pPix);
+ }
+ REGION_UNINIT(pScreen, &imageRegion);
+ REGION_UNINIT(pScreen, &censorRegion);
+} /* SecurityCensorImage */
+
+/**********************************************************************/
+
+typedef struct _PropertyAccessRec {
+ ATOM name;
+ ATOM mustHaveProperty;
+ char *mustHaveValue;
+ char windowRestriction;
+#define SecurityAnyWindow 0
+#define SecurityRootWindow 1
+#define SecurityWindowWithProperty 2
+ char readAction;
+ char writeAction;
+ char destroyAction;
+ struct _PropertyAccessRec *next;
+} PropertyAccessRec, *PropertyAccessPtr;
+
+static PropertyAccessPtr PropertyAccessList = NULL;
+static char SecurityDefaultAction = SecurityErrorOperation;
+static char *SecurityPolicyFile = DEFAULTPOLICYFILE;
+static ATOM SecurityMaxPropertyName = 0;
+
+static char *SecurityKeywords[] = {
+#define SecurityKeywordComment 0
+ "#",
+#define SecurityKeywordProperty 1
+ "property",
+#define SecurityKeywordSitePolicy 2
+ "sitepolicy",
+#define SecurityKeywordRoot 3
+ "root",
+#define SecurityKeywordAny 4
+ "any"
+};
+
+#define NUMKEYWORDS (sizeof(SecurityKeywords) / sizeof(char *))
+
+#undef PROPDEBUG
+/*#define PROPDEBUG 1*/
+
+static void
+SecurityFreePropertyAccessList()
+{
+ while (PropertyAccessList)
+ {
+ PropertyAccessPtr freeit = PropertyAccessList;
+ PropertyAccessList = PropertyAccessList->next;
+ xfree(freeit);
+ }
+} /* SecurityFreePropertyAccessList */
+
+
+#define SecurityIsWhitespace(c) ( (c == ' ') || (c == '\t') || (c == '\n') )
+
+static char *
+SecuritySkipWhitespace(p)
+ char *p;
+{
+ while (SecurityIsWhitespace(*p))
+ p++;
+ return p;
+} /* SecuritySkipWhitespace */
+
+
+static char *
+SecurityParseString(rest)
+ char **rest;
+{
+ char *startOfString;
+ char *s = *rest;
+ char endChar = 0;
+
+ s = SecuritySkipWhitespace(s);
+
+ if (*s == '"' || *s == '\'')
+ {
+ endChar = *s++;
+ startOfString = s;
+ while (*s && (*s != endChar))
+ s++;
+ }
+ else
+ {
+ startOfString = s;
+ while (*s && !SecurityIsWhitespace(*s))
+ s++;
+ }
+ if (*s)
+ {
+ *s = '\0';
+ *rest = s + 1;
+ return startOfString;
+ }
+ else
+ {
+ *rest = s;
+ return (endChar) ? NULL : startOfString;
+ }
+} /* SecurityParseString */
+
+
+static int
+SecurityParseKeyword(p)
+ char **p;
+{
+ int i;
+ char *s = *p;
+ s = SecuritySkipWhitespace(s);
+ for (i = 0; i < NUMKEYWORDS; i++)
+ {
+ int len = strlen(SecurityKeywords[i]);
+ if (strncmp(s, SecurityKeywords[i], len) == 0)
+ {
+ *p = s + len;
+ return (i);
+ }
+ }
+ *p = s;
+ return -1;
+} /* SecurityParseKeyword */
+
+
+static Bool
+SecurityParsePropertyAccessRule(p)
+ char *p;
+{
+ char *propname;
+ char c;
+ char action = SecurityDefaultAction;
+ char readAction, writeAction, destroyAction;
+ PropertyAccessPtr pacl, prev, cur;
+ ATOM atom;
+ char *mustHaveProperty = NULL;
+ char *mustHaveValue = NULL;
+ Bool invalid;
+ char windowRestriction;
+ int size;
+ int keyword;
+
+ /* get property name */
+ propname = SecurityParseString(&p);
+ if (!propname || (strlen(propname) == 0))
+ return FALSE;
+
+ /* get window on which property must reside for rule to apply */
+
+ keyword = SecurityParseKeyword(&p);
+ if (keyword == SecurityKeywordRoot)
+ windowRestriction = SecurityRootWindow;
+ else if (keyword == SecurityKeywordAny)
+ windowRestriction = SecurityAnyWindow;
+ else /* not root or any, must be a property name */
+ {
+ mustHaveProperty = SecurityParseString(&p);
+ if (!mustHaveProperty || (strlen(mustHaveProperty) == 0))
+ return FALSE;
+ windowRestriction = SecurityWindowWithProperty;
+ p = SecuritySkipWhitespace(p);
+ if (*p == '=')
+ { /* property value is specified too */
+ p++; /* skip over '=' */
+ mustHaveValue = SecurityParseString(&p);
+ if (!mustHaveValue)
+ return FALSE;
+ }
+ }
+
+ /* get operations and actions */
+
+ invalid = FALSE;
+ readAction = writeAction = destroyAction = SecurityDefaultAction;
+ while ( (c = *p++) && !invalid)
+ {
+ switch (c)
+ {
+ case 'i': action = SecurityIgnoreOperation; break;
+ case 'a': action = SecurityAllowOperation; break;
+ case 'e': action = SecurityErrorOperation; break;
+
+ case 'r': readAction = action; break;
+ case 'w': writeAction = action; break;
+ case 'd': destroyAction = action; break;
+
+ default :
+ if (!SecurityIsWhitespace(c))
+ invalid = TRUE;
+ break;
+ }
+ }
+ if (invalid)
+ return FALSE;
+
+ /* We've successfully collected all the information needed for this
+ * property access rule. Now record it in a PropertyAccessRec.
+ */
+ size = sizeof(PropertyAccessRec);
+
+ /* If there is a property value string, allocate space for it
+ * right after the PropertyAccessRec.
+ */
+ if (mustHaveValue)
+ size += strlen(mustHaveValue) + 1;
+ pacl = (PropertyAccessPtr)Xalloc(size);
+ if (!pacl)
+ return FALSE;
+
+ pacl->name = MakeAtom(propname, strlen(propname), TRUE);
+ if (pacl->name == BAD_RESOURCE)
+ {
+ Xfree(pacl);
+ return FALSE;
+ }
+ if (mustHaveProperty)
+ {
+ pacl->mustHaveProperty = MakeAtom(mustHaveProperty,
+ strlen(mustHaveProperty), TRUE);
+ if (pacl->mustHaveProperty == BAD_RESOURCE)
+ {
+ Xfree(pacl);
+ return FALSE;
+ }
+ }
+ else
+ pacl->mustHaveProperty = 0;
+
+ if (mustHaveValue)
+ {
+ pacl->mustHaveValue = (char *)(pacl + 1);
+ strcpy(pacl->mustHaveValue, mustHaveValue);
+ }
+ else
+ pacl->mustHaveValue = NULL;
+
+ SecurityMaxPropertyName = max(SecurityMaxPropertyName, pacl->name);
+
+ pacl->windowRestriction = windowRestriction;
+ pacl->readAction = readAction;
+ pacl->writeAction = writeAction;
+ pacl->destroyAction = destroyAction;
+
+ /* link the new rule into the list of rules in order of increasing
+ * property name (atom) value to make searching easier
+ */
+
+ for (prev = NULL, cur = PropertyAccessList;
+ cur && cur->name <= pacl->name;
+ prev = cur, cur = cur->next)
+ ;
+ if (!prev)
+ {
+ pacl->next = cur;
+ PropertyAccessList = pacl;
+ }
+ else
+ {
+ prev->next = pacl;
+ pacl->next = cur;
+ }
+ return TRUE;
+} /* SecurityParsePropertyAccessRule */
+
+static char **SecurityPolicyStrings = NULL;
+static int nSecurityPolicyStrings = 0;
+
+static Bool
+SecurityParseSitePolicy(p)
+ char *p;
+{
+ char *policyStr = SecurityParseString(&p);
+ char *copyPolicyStr;
+ char **newStrings;
+
+ if (!policyStr)
+ return FALSE;
+
+ copyPolicyStr = (char *)Xalloc(strlen(policyStr) + 1);
+ if (!copyPolicyStr)
+ return TRUE;
+ strcpy(copyPolicyStr, policyStr);
+ newStrings = (char **)Xrealloc(SecurityPolicyStrings,
+ sizeof (char *) * (nSecurityPolicyStrings + 1));
+ if (!newStrings)
+ {
+ Xfree(copyPolicyStr);
+ return TRUE;
+ }
+
+ SecurityPolicyStrings = newStrings;
+ SecurityPolicyStrings[nSecurityPolicyStrings++] = copyPolicyStr;
+
+ return TRUE;
+
+} /* SecurityParseSitePolicy */
+
+
+char **
+SecurityGetSitePolicyStrings(n)
+ int *n;
+{
+ *n = nSecurityPolicyStrings;
+ return SecurityPolicyStrings;
+} /* SecurityGetSitePolicyStrings */
+
+static void
+SecurityFreeSitePolicyStrings()
+{
+ if (SecurityPolicyStrings)
+ {
+ assert(nSecurityPolicyStrings);
+ while (nSecurityPolicyStrings--)
+ {
+ Xfree(SecurityPolicyStrings[nSecurityPolicyStrings]);
+ }
+ Xfree(SecurityPolicyStrings);
+ SecurityPolicyStrings = NULL;
+ nSecurityPolicyStrings = 0;
+ }
+} /* SecurityFreeSitePolicyStrings */
+
+
+static void
+SecurityLoadPropertyAccessList()
+{
+ FILE *f;
+ int lineNumber = 0;
+
+ SecurityMaxPropertyName = 0;
+
+ if (!SecurityPolicyFile)
+ return;
+
+ f = fopen(SecurityPolicyFile, "r");
+ if (!f)
+ {
+ ErrorF("error opening security policy file %s\n",
+ SecurityPolicyFile);
+ return;
+ }
+
+ while (!feof(f))
+ {
+ char buf[200];
+ Bool validLine;
+ char *p;
+
+ if (!(p = fgets(buf, sizeof(buf), f)))
+ break;
+ lineNumber++;
+
+ /* if first line, check version number */
+ if (lineNumber == 1)
+ {
+ char *v = SecurityParseString(&p);
+ if (strcmp(v, SECURITY_POLICY_FILE_VERSION) != 0)
+ {
+ ErrorF("%s: invalid security policy file version, ignoring file\n",
+ SecurityPolicyFile);
+ break;
+ }
+ validLine = TRUE;
+ }
+ else
+ {
+ switch (SecurityParseKeyword(&p))
+ {
+ case SecurityKeywordComment:
+ validLine = TRUE;
+ break;
+
+ case SecurityKeywordProperty:
+ validLine = SecurityParsePropertyAccessRule(p);
+ break;
+
+ case SecurityKeywordSitePolicy:
+ validLine = SecurityParseSitePolicy(p);
+ break;
+
+ default:
+ validLine = (*p == '\0'); /* blank lines OK, others not */
+ break;
+ }
+ }
+
+ if (!validLine)
+ ErrorF("Line %d of %s invalid, ignoring\n",
+ lineNumber, SecurityPolicyFile);
+ } /* end while more input */
+
+#ifdef PROPDEBUG
+ {
+ PropertyAccessPtr pacl;
+ char *op = "aie";
+ for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
+ {
+ ErrorF("property %s ", NameForAtom(pacl->name));
+ switch (pacl->windowRestriction)
+ {
+ case SecurityAnyWindow: ErrorF("any "); break;
+ case SecurityRootWindow: ErrorF("root "); break;
+ case SecurityWindowWithProperty:
+ {
+ ErrorF("%s ", NameForAtom(pacl->mustHaveProperty));
+ if (pacl->mustHaveValue)
+ ErrorF(" = \"%s\" ", pacl->mustHaveValue);
+
+ }
+ break;
+ }
+ ErrorF("%cr %cw %cd\n", op[pacl->readAction],
+ op[pacl->writeAction], op[pacl->destroyAction]);
+ }
+ }
+#endif /* PROPDEBUG */
+
+ fclose(f);
+} /* SecurityLoadPropertyAccessList */
+
+
+static Bool
+SecurityMatchString(ws, cs)
+ char *ws;
+ char *cs;
+{
+ while (*ws && *cs)
+ {
+ if (*ws == '*')
+ {
+ Bool match = FALSE;
+ ws++;
+ while (!(match = SecurityMatchString(ws, cs)) && *cs)
+ {
+ cs++;
+ }
+ return match;
+ }
+ else if (*ws == *cs)
+ {
+ ws++;
+ cs++;
+ }
+ else break;
+ }
+ return ( ( (*ws == '\0') || ((*ws == '*') && *(ws+1) == '\0') )
+ && (*cs == '\0') );
+} /* SecurityMatchString */
+
+#ifdef PROPDEBUG
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+
+char
+SecurityCheckPropertyAccess(client, pWin, propertyName, access_mode)
+ ClientPtr client;
+ WindowPtr pWin;
+ ATOM propertyName;
+ Mask access_mode;
+{
+ PropertyAccessPtr pacl;
+ char action = SecurityDefaultAction;
+
+ /* if client trusted or window untrusted, allow operation */
+
+ if ( (client->trustLevel == XSecurityClientTrusted) ||
+ (wClient(pWin)->trustLevel != XSecurityClientTrusted) )
+ return SecurityAllowOperation;
+
+#ifdef PROPDEBUG
+ /* For testing, it's more convenient if the property rules file gets
+ * reloaded whenever it changes, so we can rapidly try things without
+ * having to reset the server.
+ */
+ {
+ struct stat buf;
+ static time_t lastmod = 0;
+ int ret = stat(SecurityPolicyFile , &buf);
+ if ( (ret == 0) && (buf.st_mtime > lastmod) )
+ {
+ ErrorF("reloading property rules\n");
+ SecurityFreePropertyAccessList();
+ SecurityLoadPropertyAccessList();
+ lastmod = buf.st_mtime;
+ }
+ }
+#endif
+
+ /* If the property atom is bigger than any atoms on the list,
+ * we know we won't find it, so don't even bother looking.
+ */
+ if (propertyName <= SecurityMaxPropertyName)
+ {
+ /* untrusted client operating on trusted window; see if it's allowed */
+
+ for (pacl = PropertyAccessList; pacl; pacl = pacl->next)
+ {
+ if (pacl->name < propertyName)
+ continue;
+ if (pacl->name > propertyName)
+ break;
+
+ /* pacl->name == propertyName, so see if it applies to this window */
+
+ switch (pacl->windowRestriction)
+ {
+ case SecurityAnyWindow: /* always applies */
+ break;
+
+ case SecurityRootWindow:
+ {
+ /* if not a root window, this rule doesn't apply */
+ if (pWin->parent)
+ continue;
+ }
+ break;
+
+ case SecurityWindowWithProperty:
+ {
+ PropertyPtr pProp = wUserProps (pWin);
+ Bool match = FALSE;
+ char *p;
+ char *pEndData;
+
+ while (pProp)
+ {
+ if (pProp->propertyName == pacl->mustHaveProperty)
+ break;
+ pProp = pProp->next;
+ }
+ if (!pProp)
+ continue;
+ if (!pacl->mustHaveValue)
+ break;
+ if (pProp->type != XA_STRING || pProp->format != 8)
+ continue;
+
+ p = pProp->data;
+ pEndData = ((char *)pProp->data) + pProp->size;
+ while (!match && p < pEndData)
+ {
+ if (SecurityMatchString(pacl->mustHaveValue, p))
+ match = TRUE;
+ else
+ { /* skip to the next string */
+ while (*p++ && p < pEndData)
+ ;
+ }
+ }
+ if (!match)
+ continue;
+ }
+ break; /* end case SecurityWindowWithProperty */
+ } /* end switch on windowRestriction */
+
+ /* If we get here, the property access rule pacl applies.
+ * If pacl doesn't apply, something above should have
+ * executed a continue, which will skip the follwing code.
+ */
+ action = SecurityAllowOperation;
+ if (access_mode & SecurityReadAccess)
+ action = max(action, pacl->readAction);
+ if (access_mode & SecurityWriteAccess)
+ action = max(action, pacl->writeAction);
+ if (access_mode & SecurityDestroyAccess)
+ action = max(action, pacl->destroyAction);
+ break;
+ } /* end for each pacl */
+ } /* end if propertyName <= SecurityMaxPropertyName */
+
+ if (SecurityAllowOperation != action)
+ { /* audit the access violation */
+ int cid = CLIENT_ID(pWin->drawable.id);
+ int reqtype = ((xReq *)client->requestBuffer)->reqType;
+ char *actionstr = (SecurityIgnoreOperation == action) ?
+ "ignored" : "error";
+ SecurityAudit("client %d attempted request %d with window 0x%x property %s (atom 0x%x) of client %d, %s\n",
+ client->index, reqtype, pWin->drawable.id,
+ NameForAtom(propertyName), propertyName, cid, actionstr);
+ }
+ return action;
+} /* SecurityCheckPropertyAccess */
+
+
+/* SecurityResetProc
+ *
+ * Arguments:
+ * extEntry is the extension information for the security extension.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by Security at server shutdown time.
+ */
+
+static void
+SecurityResetProc(extEntry)
+ ExtensionEntry *extEntry;
+{
+ SecurityFreePropertyAccessList();
+ SecurityFreeSitePolicyStrings();
+} /* SecurityResetProc */
+
+
+int
+XSecurityOptions(argc, argv, i)
+ int argc;
+ char **argv;
+ int i;
+{
+ if (strcmp(argv[i], "-sp") == 0)
+ {
+ if (i < argc)
+ SecurityPolicyFile = argv[++i];
+ return (i + 1);
+ }
+ return (i);
+} /* XSecurityOptions */
+
+
+
+/* SecurityExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Enables the Security extension if possible.
+ */
+
+void
+SecurityExtensionInit()
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+ SecurityAuthorizationResType =
+ CreateNewResourceType(SecurityDeleteAuthorization);
+
+ RTEventClient = CreateNewResourceType(
+ SecurityDeleteAuthorizationEventClient);
+
+ if (!SecurityAuthorizationResType || !RTEventClient)
+ return;
+
+ RTEventClient |= RC_NEVERRETAIN;
+
+ if (!AddCallback(&ClientStateCallback, SecurityClientStateCallback, NULL))
+ return;
+
+ extEntry = AddExtension(SECURITY_EXTENSION_NAME,
+ XSecurityNumberEvents, XSecurityNumberErrors,
+ ProcSecurityDispatch, SProcSecurityDispatch,
+ SecurityResetProc, StandardMinorOpcode);
+
+ SecurityErrorBase = extEntry->errorBase;
+ SecurityEventBase = extEntry->eventBase;
+
+ EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] =
+ SwapSecurityAuthorizationRevokedEvent;
+
+ /* initialize untrusted proc vectors */
+
+ for (i = 0; i < 128; i++)
+ {
+ UntrustedProcVector[i] = ProcVector[i];
+ SwappedUntrustedProcVector[i] = SwappedProcVector[i];
+ }
+
+ /* make sure insecure extensions are not allowed */
+
+ for (i = 128; i < 256; i++)
+ {
+ if (!UntrustedProcVector[i])
+ {
+ UntrustedProcVector[i] = ProcBadRequest;
+ SwappedUntrustedProcVector[i] = ProcBadRequest;
+ }
+ }
+
+ SecurityLoadPropertyAccessList();
+
+} /* SecurityExtensionInit */
diff --git a/Xext/shape.c b/Xext/shape.c
new file mode 100644
index 000000000..bff7d2502
--- /dev/null
+++ b/Xext/shape.c
@@ -0,0 +1,1217 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* $Xorg: shape.c,v 1.4 2001/02/09 02:04:32 xorgcvs Exp $ */
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#define _SHAPE_SERVER_ /* don't want Xlib structures */
+#include "shapestr.h"
+#include "regionstr.h"
+#include "gcstruct.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#endif
+
+static int ShapeFreeClient(), ShapeFreeEvents();
+static void SendShapeNotify();
+static int ProcShapeDispatch(), SProcShapeDispatch();
+static void ShapeResetProc(), SShapeNotifyEvent();
+
+static unsigned char ShapeReqCode = 0;
+static int ShapeEventBase = 0;
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+
+#ifdef PANORAMIX
+extern int PanoramiXNumScreens;
+extern Bool noPanoramiXExtension;
+extern PanoramiXWindow *PanoramiXWinRoot;
+extern PanoramiXPmap *PanoramiXPmapRoot;
+#endif
+/*
+ * each window has a list of clients requesting
+ * ShapeNotify events. Each client has a resource
+ * for each window it selects ShapeNotify input for,
+ * this resource is used to delete the ShapeNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _ShapeEvent *ShapeEventPtr;
+
+typedef struct _ShapeEvent {
+ ShapeEventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+} ShapeEventRec;
+
+/****************
+ * ShapeExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+
+void
+ShapeExtensionInit()
+{
+ ExtensionEntry *extEntry, *AddExtension();
+
+ ClientType = CreateNewResourceType(ShapeFreeClient);
+ EventType = CreateNewResourceType(ShapeFreeEvents);
+ if (ClientType && EventType &&
+ (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
+ ProcShapeDispatch, SProcShapeDispatch,
+ ShapeResetProc, StandardMinorOpcode)))
+ {
+ ShapeReqCode = (unsigned char)extEntry->base;
+ ShapeEventBase = extEntry->eventBase;
+ EventSwapVector[ShapeEventBase] = SShapeNotifyEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShapeResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+}
+
+static
+RegionOperate (client, pWin, kind, destRgnp, srcRgn, op, xoff, yoff, create)
+ ClientPtr client;
+ WindowPtr pWin;
+ int kind;
+ RegionPtr *destRgnp, srcRgn;
+ int op;
+ int xoff, yoff;
+ RegionPtr (*create)(); /* creates a reasonable *destRgnp */
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (srcRgn && (xoff || yoff))
+ REGION_TRANSLATE(pScreen, srcRgn, xoff, yoff);
+ if (!pWin->parent)
+ {
+ if (srcRgn)
+ REGION_DESTROY(pScreen, srcRgn);
+ return Success;
+ }
+ switch (op) {
+ case ShapeSet:
+ if (*destRgnp)
+ REGION_DESTROY(pScreen, *destRgnp);
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ break;
+ case ShapeUnion:
+ if (*destRgnp)
+ REGION_UNION(pScreen, *destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeIntersect:
+ if (*destRgnp)
+ REGION_INTERSECT(pScreen, *destRgnp, *destRgnp, srcRgn);
+ else {
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ }
+ break;
+ case ShapeSubtract:
+ if (!*destRgnp)
+ *destRgnp = (*create)(pWin);
+ REGION_SUBTRACT(pScreen, *destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeInvert:
+ if (!*destRgnp)
+ *destRgnp = REGION_CREATE(pScreen, (BoxPtr) 0, 0);
+ else
+ REGION_SUBTRACT(pScreen, *destRgnp, srcRgn, *destRgnp);
+ break;
+ default:
+ client->errorValue = op;
+ return BadValue;
+ }
+ if (srcRgn)
+ REGION_DESTROY(pScreen, srcRgn);
+ (*pScreen->SetShape) (pWin);
+ SendShapeNotify (pWin, kind);
+ return Success;
+}
+
+static RegionPtr
+CreateBoundingShape (pWin)
+ WindowPtr pWin;
+{
+ BoxRec extents;
+
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ return REGION_CREATE(pWin->drawable.pScreen, &extents, 1);
+}
+
+static RegionPtr
+CreateClipShape (pWin)
+ WindowPtr pWin;
+{
+ BoxRec extents;
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ return REGION_CREATE(pWin->drawable.pScreen, &extents, 1);
+}
+
+static int
+ProcShapeQueryVersion (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeQueryVersionReq);
+ xShapeQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xShapeQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SHAPE_MAJOR_VERSION;
+ rep.minorVersion = SHAPE_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof (xShapeQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+/*****************
+ * ProcShapeRectangles
+ *
+ *****************/
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeRectangles (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeRectanglesReq);
+ xRectangle *prects;
+ int nrects, ctype;
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ RegionPtr (*createDefault)();
+ int destBounding;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->dest);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->dest = pPanoramiXWin->info[j].id;
+ result = ProcShapeRectangles (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcShapeRectangles (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeRectanglesReq);
+ xRectangle *prects;
+ int nrects, ctype;
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ RegionPtr (*createDefault)();
+ int destBounding;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ UpdateCurrentTime();
+ pWin = LookupWindow (stuff->dest, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destBounding = 1;
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ destBounding = 0;
+ createDefault = CreateClipShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq));
+ if (nrects & 4)
+ return BadLength;
+ nrects >>= 3;
+ prects = (xRectangle *) &stuff[1];
+ ctype = VerifyRectOrder(nrects, prects, (int)stuff->ordering);
+ if (ctype < 0)
+ return BadMatch;
+ srcRgn = RECTS_TO_REGION(pScreen, nrects, prects, ctype);
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ if (destBounding)
+ destRgn = &pWin->optional->boundingShape;
+ else
+ destRgn = &pWin->optional->clipShape;
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+/**************
+ * ProcShapeMask
+ **************/
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeMask (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeMaskReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ PixmapPtr pPixmap;
+ RegionPtr (*createDefault)();
+ int destBounding;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+ PanoramiXPmap *pPmap = PanoramiXPmapRoot;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->dest);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ PANORAMIXFIND_ID(pPmap, stuff->src);
+ IF_RETURN(!pPmap, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->dest = pPanoramiXWin->info[j].id;
+ stuff->src = pPmap->info[j].id;
+ result = ProcShapeMask (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcShapeMask (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeMaskReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ PixmapPtr pPixmap;
+ RegionPtr (*createDefault)();
+ int destBounding;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ UpdateCurrentTime();
+ pWin = SecurityLookupWindow (stuff->dest, client, SecurityWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destBounding = 1;
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ destBounding = 0;
+ createDefault = CreateClipShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (stuff->src == None)
+ srcRgn = 0;
+ else {
+ pPixmap = (PixmapPtr) SecurityLookupIDByType(client, stuff->src,
+ RT_PIXMAP, SecurityReadAccess);
+ if (!pPixmap)
+ return BadPixmap;
+ if (pPixmap->drawable.pScreen != pScreen ||
+ pPixmap->drawable.depth != 1)
+ return BadMatch;
+ srcRgn = BITMAP_TO_REGION(pScreen, pPixmap);
+ if (!srcRgn)
+ return BadAlloc;
+ }
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ if (destBounding)
+ destRgn = &pWin->optional->boundingShape;
+ else
+ destRgn = &pWin->optional->clipShape;
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+/************
+ * ProcShapeCombine
+ ************/
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeCombine (client)
+ register ClientPtr client;
+{
+ WindowPtr pSrcWin, pDestWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeCombineReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ RegionPtr (*createDefault)();
+ RegionPtr (*createSrc)();
+ RegionPtr tmp;
+ int destBounding;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_AT_LEAST_SIZE (xShapeCombineReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->dest);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->dest = pPanoramiXWin->info[j].id;
+ result = ProcShapeCombine (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcShapeCombine (client)
+ register ClientPtr client;
+{
+ WindowPtr pSrcWin, pDestWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeCombineReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ RegionPtr (*createDefault)();
+ RegionPtr (*createSrc)();
+ RegionPtr tmp;
+ int destBounding;
+
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ UpdateCurrentTime();
+ pDestWin = LookupWindow (stuff->dest, client);
+ if (!pDestWin)
+ return BadWindow;
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destBounding = 1;
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ destBounding = 0;
+ createDefault = CreateClipShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pDestWin->drawable.pScreen;
+
+ pSrcWin = LookupWindow (stuff->src, client);
+ if (!pSrcWin)
+ return BadWindow;
+ switch (stuff->srcKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape (pSrcWin);
+ createSrc = CreateClipShape;
+ break;
+ default:
+ client->errorValue = stuff->srcKind;
+ return BadValue;
+ }
+ if (pSrcWin->drawable.pScreen != pScreen)
+ {
+ return BadMatch;
+ }
+
+ if (srcRgn) {
+ tmp = REGION_CREATE(pScreen, (BoxPtr) 0, 0);
+ REGION_COPY(pScreen, tmp, srcRgn);
+ srcRgn = tmp;
+ } else
+ srcRgn = (*createSrc) (pSrcWin);
+
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ if (destBounding)
+ destRgn = &pDestWin->optional->boundingShape;
+ else
+ destRgn = &pDestWin->optional->clipShape;
+
+ return RegionOperate (client, pDestWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+/*************
+ * ProcShapeOffset
+ *************/
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeOffset (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeOffsetReq);
+ RegionPtr srcRgn;
+
+ register int result;
+ int j;
+ PanoramiXWindow *pPanoramiXWin = PanoramiXWinRoot;
+
+ REQUEST_AT_LEAST_SIZE (xShapeOffsetReq);
+ PANORAMIXFIND_ID(pPanoramiXWin,stuff->dest);
+ IF_RETURN(!pPanoramiXWin, BadRequest);
+ FOR_NSCREENS_OR_ONCE(pPanoramiXWin , j) {
+ stuff->dest = pPanoramiXWin->info[j].id;
+ result = ProcShapeOffset (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+#ifdef PANORAMIX
+int
+#else
+static int
+#endif
+ProcShapeOffset (client)
+ register ClientPtr client;
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeOffsetReq);
+ RegionPtr srcRgn;
+
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ UpdateCurrentTime();
+ pWin = LookupWindow (stuff->dest, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pWin);
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape(pWin);
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (srcRgn)
+ {
+ REGION_TRANSLATE(pScreen, srcRgn, stuff->xOff, stuff->yOff);
+ (*pScreen->SetShape) (pWin);
+ }
+ SendShapeNotify (pWin, (int)stuff->destKind);
+ return Success;
+}
+
+static int
+ProcShapeQueryExtents (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeQueryExtentsReq);
+ WindowPtr pWin;
+ xShapeQueryExtentsReply rep;
+ BoxRec extents, *pExtents;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.boundingShaped = (wBoundingShape(pWin) != 0);
+ rep.clipShaped = (wClipShape(pWin) != 0);
+ if (wBoundingShape(pWin)) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = REGION_EXTENTS(pWin->drawable.pScreen, wBoundingShape(pWin));
+ extents = *pExtents;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ }
+ rep.xBoundingShape = extents.x1;
+ rep.yBoundingShape = extents.y1;
+ rep.widthBoundingShape = extents.x2 - extents.x1;
+ rep.heightBoundingShape = extents.y2 - extents.y1;
+ if (wClipShape(pWin)) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = REGION_EXTENTS(pWin->drawable.pScreen, wClipShape(pWin));
+ extents = *pExtents;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ }
+ rep.xClipShape = extents.x1;
+ rep.yClipShape = extents.y1;
+ rep.widthClipShape = extents.x2 - extents.x1;
+ rep.heightClipShape = extents.y2 - extents.y1;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.xBoundingShape, n);
+ swaps(&rep.yBoundingShape, n);
+ swaps(&rep.widthBoundingShape, n);
+ swaps(&rep.heightBoundingShape, n);
+ swaps(&rep.xClipShape, n);
+ swaps(&rep.yClipShape, n);
+ swaps(&rep.widthClipShape, n);
+ swaps(&rep.heightClipShape, n);
+ }
+ WriteToClient(client, sizeof (xShapeQueryExtentsReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeClient (data, id)
+ pointer data;
+ XID id;
+{
+ ShapeEventPtr pShapeEvent;
+ WindowPtr pWin;
+ ShapeEventPtr *pHead, pCur, pPrev;
+
+ pShapeEvent = (ShapeEventPtr) data;
+ pWin = pShapeEvent->window;
+ pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ }
+ }
+ xfree ((pointer) pShapeEvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeEvents (data, id)
+ pointer data;
+ XID id;
+{
+ ShapeEventPtr *pHead, pCur, pNext;
+
+ pHead = (ShapeEventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ return 1;
+}
+
+static int
+ProcShapeSelectInput (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeSelectInputReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ pWin = SecurityLookupWindow (stuff->window, client, SecurityWriteAccess);
+ if (!pWin)
+ return BadWindow;
+ pHead = (ShapeEventPtr *)SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType, SecurityWriteAccess);
+ switch (stuff->enable) {
+ case xTrue:
+ if (pHead) {
+
+ /* check for existing entry. */
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client)
+ return Success;
+ }
+ }
+
+ /* build the entry */
+ pNewShapeEvent = (ShapeEventPtr)
+ xalloc (sizeof (ShapeEventRec));
+ if (!pNewShapeEvent)
+ return BadAlloc;
+ pNewShapeEvent->next = 0;
+ pNewShapeEvent->client = client;
+ pNewShapeEvent->window = pWin;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewShapeEvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewShapeEvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (ShapeEventPtr *) xalloc (sizeof (ShapeEventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, EventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewShapeEvent->next = *pHead;
+ *pHead = pNewShapeEvent;
+ break;
+ case xFalse:
+ /* delete the interest */
+ if (pHead) {
+ pNewShapeEvent = 0;
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ if (pShapeEvent->client == client)
+ break;
+ pNewShapeEvent = pShapeEvent;
+ }
+ if (pShapeEvent) {
+ FreeResource (pShapeEvent->clientResource, ClientType);
+ if (pNewShapeEvent)
+ pNewShapeEvent->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ xfree (pShapeEvent);
+ }
+ }
+ break;
+ default:
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+/*
+ * deliver the event
+ */
+
+static void
+SendShapeNotify (pWin, which)
+ WindowPtr pWin;
+ int which;
+{
+ ShapeEventPtr *pHead, pShapeEvent;
+ ClientPtr client;
+ xShapeNotifyEvent se;
+ BoxRec extents;
+ RegionPtr region;
+ BYTE shaped;
+
+ pHead = (ShapeEventPtr *) LookupIDByType(pWin->drawable.id, EventType);
+ if (!pHead)
+ return;
+ if (which == ShapeBounding) {
+ region = wBoundingShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ } else {
+ region = wClipShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ shaped = xFalse;
+ }
+ }
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ client = pShapeEvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+ se.type = ShapeNotify + ShapeEventBase;
+ se.kind = which;
+ se.window = pWin->drawable.id;
+ se.sequenceNumber = client->sequence;
+ se.x = extents.x1;
+ se.y = extents.y1;
+ se.width = extents.x2 - extents.x1;
+ se.height = extents.y2 - extents.y1;
+ se.time = currentTime.milliseconds;
+ se.shaped = shaped;
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+}
+
+static int
+ProcShapeInputSelected (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeInputSelectedReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, *pHead;
+ int enabled;
+ xShapeInputSelectedReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ pHead = (ShapeEventPtr *) SecurityLookupIDByType(client,
+ pWin->drawable.id, EventType, SecurityReadAccess);
+ enabled = xFalse;
+ if (pHead) {
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client) {
+ enabled = xTrue;
+ break;
+ }
+ }
+ }
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.enabled = enabled;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ }
+ WriteToClient (client, sizeof (xShapeInputSelectedReply), (char *) &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcShapeGetRectangles (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeGetRectanglesReq);
+ WindowPtr pWin;
+ xShapeGetRectanglesReply rep;
+ xRectangle *rects;
+ int nrects, i;
+ RegionPtr region;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ pWin = LookupWindow (stuff->window, client);
+ if (!pWin)
+ return BadWindow;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ region = wBoundingShape(pWin);
+ break;
+ case ShapeClip:
+ region = wClipShape(pWin);
+ break;
+ default:
+ client->errorValue = stuff->kind;
+ return BadValue;
+ }
+ if (!region) {
+ nrects = 1;
+ rects = (xRectangle *) ALLOCATE_LOCAL (sizeof (xRectangle));
+ if (!rects)
+ return BadAlloc;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
+ case ShapeClip:
+ rects->x = 0;
+ rects->y = 0;
+ rects->width = pWin->drawable.width;
+ rects->height = pWin->drawable.height;
+ break;
+ }
+ } else {
+ BoxPtr box;
+ nrects = REGION_NUM_RECTS(region);
+ box = REGION_RECTS(region);
+ rects = (xRectangle *) ALLOCATE_LOCAL (nrects * sizeof (xRectangle));
+ if (!rects && nrects)
+ return BadAlloc;
+ for (i = 0; i < nrects; i++, box++) {
+ rects[i].x = box->x1;
+ rects[i].y = box->y1;
+ rects[i].width = box->x2 - box->x1;
+ rects[i].height = box->y2 - box->y1;
+ }
+ }
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = (nrects * sizeof (xRectangle)) >> 2;
+ rep.ordering = YXBanded;
+ rep.nrects = nrects;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swapl (&rep.nrects, n);
+ SwapShorts ((short *)rects, (unsigned long)nrects * 4);
+ }
+ WriteToClient (client, sizeof (rep), (char *) &rep);
+ WriteToClient (client, nrects * sizeof (xRectangle), (char *) rects);
+ DEALLOCATE_LOCAL (rects);
+ return client->noClientException;
+}
+
+static int
+ProcShapeDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return ProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeRectangles (client);
+ else
+ return ProcShapeRectangles (client);
+#else
+ return ProcShapeRectangles (client);
+#endif
+ case X_ShapeMask:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeMask (client);
+ else
+ return ProcShapeMask (client);
+#else
+ return ProcShapeMask (client);
+#endif
+ case X_ShapeCombine:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeCombine (client);
+ else
+ return ProcShapeCombine (client);
+#else
+ return ProcShapeCombine (client);
+#endif
+ case X_ShapeOffset:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeOffset (client);
+ else
+ return ProcShapeOffset (client);
+#else
+ return ProcShapeOffset (client);
+#endif
+ case X_ShapeQueryExtents:
+ return ProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return ProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return ProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return ProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SShapeNotifyEvent(from, to)
+ xShapeNotifyEvent *from, *to;
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswapl (from->window, to->window);
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswaps (from->x, to->x);
+ cpswaps (from->y, to->y);
+ cpswaps (from->width, to->width);
+ cpswaps (from->height, to->height);
+ cpswapl (from->time, to->time);
+ to->shaped = from->shaped;
+}
+
+static int
+SProcShapeQueryVersion (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xShapeQueryVersionReq);
+
+ swaps (&stuff->length, n);
+ return ProcShapeQueryVersion (client);
+}
+
+static int
+SProcShapeRectangles (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeRectanglesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ SwapRestS(stuff);
+ return ProcShapeRectangles (client);
+}
+
+static int
+SProcShapeMask (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeMaskReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ swapl (&stuff->src, n);
+ return ProcShapeMask (client);
+}
+
+static int
+SProcShapeCombine (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeCombineReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ swapl (&stuff->src, n);
+ return ProcShapeCombine (client);
+}
+
+static int
+SProcShapeOffset (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeOffsetReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ return ProcShapeOffset (client);
+}
+
+static int
+SProcShapeQueryExtents (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeQueryExtentsReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ swapl (&stuff->window, n);
+ return ProcShapeQueryExtents (client);
+}
+
+static int
+SProcShapeSelectInput (client)
+ register ClientPtr client;
+{
+ register char n;
+ REQUEST (xShapeSelectInputReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ swapl (&stuff->window, n);
+ return ProcShapeSelectInput (client);
+}
+
+static int
+SProcShapeInputSelected (client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST (xShapeInputSelectedReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ swapl (&stuff->window, n);
+ return ProcShapeInputSelected (client);
+}
+
+static int
+SProcShapeGetRectangles (client)
+ register ClientPtr client;
+{
+ REQUEST(xShapeGetRectanglesReq);
+ register char n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ swapl (&stuff->window, n);
+ return ProcShapeGetRectangles (client);
+}
+
+static int
+SProcShapeDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return SProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+ return SProcShapeRectangles (client);
+ case X_ShapeMask:
+ return SProcShapeMask (client);
+ case X_ShapeCombine:
+ return SProcShapeCombine (client);
+ case X_ShapeOffset:
+ return SProcShapeOffset (client);
+ case X_ShapeQueryExtents:
+ return SProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return SProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return SProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return SProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/Xext/shm.c b/Xext/shm.c
new file mode 100644
index 000000000..0a9f3af59
--- /dev/null
+++ b/Xext/shm.c
@@ -0,0 +1,1010 @@
+/************************************************************
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+/* $Xorg: shm.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include "X.h"
+#include "Xproto.h"
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#define _XSHM_SERVER_
+#include "shmstr.h"
+#include "Xfuncproto.h"
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+static void miShmPutImage(), fbShmPutImage();
+static PixmapPtr fbShmCreatePixmap();
+static int ProcShmDispatch(), SProcShmDispatch();
+static int ShmDetachSegment();
+static void ShmResetProc(), SShmCompletionEvent();
+
+static unsigned char ShmReqCode;
+static int ShmCompletionCode;
+static int BadShmSegCode;
+static RESTYPE ShmSegType, ShmPixType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int pixmapFormat;
+static int shmPixFormat[MAXSCREENS];
+static ShmFuncsPtr shmFuncs[MAXSCREENS];
+static ShmFuncs miFuncs = {NULL, miShmPutImage};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ shmdesc = (ShmDescPtr)LookupIDByType(shmseg, ShmSegType); \
+ if (!shmdesc) \
+ { \
+ client->errorValue = shmseg; \
+ return BadShmSegCode; \
+ } \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+ VERIFY_SHMSEG(shmseg, shmdesc, client); \
+ if ((offset & 3) || (offset > shmdesc->size)) \
+ { \
+ client->errorValue = offset; \
+ return BadValue; \
+ } \
+ if (needwrite && !shmdesc->writable) \
+ return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+ if ((offset + len) > shmdesc->size) \
+ { \
+ return BadAccess; \
+ } \
+}
+
+void
+ShmExtensionInit()
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+#else
+ sharedPixmaps = xTrue;
+ pixmapFormat = shmPixFormat[0];
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ if (!shmFuncs[i])
+ shmFuncs[i] = &miFuncs;
+ if (!shmFuncs[i]->CreatePixmap)
+ sharedPixmaps = xFalse;
+ if (shmPixFormat[i] && (shmPixFormat[i] != pixmapFormat))
+ {
+ sharedPixmaps = xFalse;
+ pixmapFormat = 0;
+ }
+ }
+ if (!pixmapFormat)
+ pixmapFormat = ZPixmap;
+#endif
+ ShmSegType = CreateNewResourceType(ShmDetachSegment);
+ ShmPixType = CreateNewResourceType(ShmDetachSegment);
+ if (ShmSegType && ShmPixType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = SShmCompletionEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc (extEntry)
+ExtensionEntry *extEntry;
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++)
+ {
+ shmFuncs[i] = (ShmFuncsPtr)NULL;
+ shmPixFormat[i] = 0;
+ }
+}
+
+void
+ShmRegisterFuncs(pScreen, funcs)
+ ScreenPtr pScreen;
+ ShmFuncsPtr funcs;
+{
+ shmFuncs[pScreen->myNum] = funcs;
+}
+
+void
+ShmSetPixmapFormat(pScreen, format)
+ ScreenPtr pScreen;
+ int format;
+{
+ shmPixFormat[pScreen->myNum] = format;
+}
+
+void
+ShmRegisterFbFuncs(pScreen)
+ ScreenPtr pScreen;
+{
+ shmFuncs[pScreen->myNum] = &fbFuncs;
+}
+
+static int
+ProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ REQUEST(xShmQueryVersionReq);
+ xShmQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = pixmapFormat;
+ rep.majorVersion = SHM_MAJOR_VERSION;
+ rep.minorVersion = SHM_MINOR_VERSION;
+ rep.uid = geteuid();
+ rep.gid = getegid();
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swaps(&rep.uid, n);
+ swaps(&rep.gid, n);
+ }
+ WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcShmAttach(client)
+ register ClientPtr client;
+{
+ struct shmid_ds buf;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmAttachReq);
+
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+ if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+ {
+ client->errorValue = stuff->readOnly;
+ return(BadValue);
+ }
+ for (shmdesc = Shmsegs;
+ shmdesc && (shmdesc->shmid != stuff->shmid);
+ shmdesc = shmdesc->next)
+ ;
+ if (shmdesc)
+ {
+ if (!stuff->readOnly && !shmdesc->writable)
+ return BadAccess;
+ shmdesc->refcnt++;
+ }
+ else
+ {
+ shmdesc = (ShmDescPtr) xalloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ shmctl(stuff->shmid, IPC_STAT, &buf))
+ {
+ xfree(shmdesc);
+ return BadAccess;
+ }
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = buf.shm_segsz;
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(value, shmseg)
+ pointer value; /* must conform to DeleteType */
+ XID shmseg;
+{
+ ShmDescPtr shmdesc = (ShmDescPtr)value;
+ ShmDescPtr *prev;
+
+ if (--shmdesc->refcnt)
+ return TRUE;
+ shmdt(shmdesc->addr);
+ for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+ ;
+ *prev = shmdesc->next;
+ xfree(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(client)
+ register ClientPtr client;
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+static void
+miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ PixmapPtr pmap;
+ GCPtr putGC;
+
+ putGC = GetScratchGC(depth, dst->pScreen);
+ if (!putGC)
+ return;
+ pmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth);
+ if (!pmap)
+ {
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC((DrawablePtr)pmap, putGC);
+ (*putGC->ops->PutImage)((DrawablePtr)pmap, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pmap, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pmap->drawable.pScreen->DestroyPixmap)(pmap);
+}
+
+static void
+fbShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy, data)
+ DrawablePtr dst;
+ GCPtr pGC;
+ int depth, w, h, sx, sy, sw, sh, dx, dy;
+ unsigned int format;
+ char *data;
+{
+ if ((format == ZPixmap) || (depth == 1))
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ /*XXX*/depth, PixmapBytePad(w, depth), (pointer)data);
+ if (!pPixmap)
+ return;
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)((DrawablePtr)pPixmap, dst, pGC,
+ sx, sy, sw, sh, dx, dy);
+ FreeScratchPixmapHeader(pPixmap);
+ }
+ else
+ miShmPutImage(dst, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+}
+
+static int
+ProcShmPutImage(client)
+ register ClientPtr client;
+{
+ register GCPtr pGC;
+ register DrawablePtr pDraw;
+ long length;
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ long lengthProto;
+ char *tmpImage;
+ int tmpAlloced = 0;
+#endif
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, pGC, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+ if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+ return BadValue;
+ if (stuff->format == XYBitmap)
+ {
+ if (stuff->depth != 1)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ lengthProto = PixmapBytePadProto(stuff->totalWidth, 1);
+#endif
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ length *= stuff->depth;
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ lengthProto = PixmapBytePadProto(stuff->totalWidth, 1);
+ lengthProto *= stuff->depth;
+#endif
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ lengthProto = PixmapBytePadProto(stuff->totalWidth, stuff->depth);
+#endif
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, lengthProto * stuff->totalHeight,
+ client);
+#else
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ client);
+#endif
+ if (stuff->srcX > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcX;
+ return BadValue;
+ }
+ if (stuff->srcY > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcY;
+ return BadValue;
+ }
+ if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcWidth;
+ return BadValue;
+ }
+ if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcHeight;
+ return BadValue;
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /* handle 64 bit case where protocol may pad to 32 and we want 64
+ * In this case, length is what the server wants and lengthProto is
+ * what the protocol thinks it is. If the the two are different,
+ * copy the protocol version (i.e. the memory shared between the
+ * server and the client) to a version with a scanline pad of 64.
+ */
+ if (length != lengthProto)
+ {
+ register int i;
+ char * stuffptr, /* pointer into protocol data */
+ * tmpptr; /* new location to copy to */
+
+ if(!(tmpImage = (char *) ALLOCATE_LOCAL(length*stuff->totalHeight)))
+ return (BadAlloc);
+ tmpAlloced = 1;
+
+ bzero(tmpImage,length*stuff->totalHeight);
+
+ if (stuff->format == XYPixmap)
+ {
+ int lineBytes = PixmapBytePad(stuff->totalWidth, 1);
+ int lineBytesProto = PixmapBytePadProto(stuff->totalWidth, 1);
+ int depth = stuff->depth;
+
+ stuffptr = shmdesc->addr + stuff->offset ;
+ tmpptr = tmpImage;
+ for (i = 0; i < stuff->totalHeight*stuff->depth;
+ stuffptr += lineBytesProto,tmpptr += lineBytes, i++)
+ bcopy(stuffptr,tmpptr,lineBytesProto);
+ }
+ else
+ {
+ for (i = 0,
+ stuffptr = shmdesc->addr + stuff->offset,
+ tmpptr=tmpImage;
+ i < stuff->totalHeight;
+ stuffptr += lengthProto,tmpptr += length, i++)
+ bcopy(stuffptr,tmpptr,lengthProto);
+ }
+ }
+ /* handle 64-bit case where stuff is not 64-bit aligned
+ */
+ else if ((unsigned long)(shmdesc->addr+stuff->offset) &
+ (sizeof(long)-1))
+ {
+ if(!(tmpImage = (char *) ALLOCATE_LOCAL(length*stuff->totalHeight)))
+ return (BadAlloc);
+ tmpAlloced = 1;
+ bcopy((char *)(shmdesc->addr+stuff->offset),
+ tmpImage,
+ length*stuff->totalHeight);
+ }
+ else
+ tmpImage = (char *)(shmdesc->addr+stuff->offset);
+#endif
+
+ if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+ ((stuff->format != ZPixmap) &&
+ (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+ ((stuff->format == XYBitmap) ||
+ ((stuff->srcY == 0) &&
+ (stuff->srcHeight == stuff->totalHeight))))) &&
+ ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+ stuff->dstX, stuff->dstY,
+ stuff->totalWidth, stuff->srcHeight,
+ stuff->srcX, stuff->format,
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ tmpImage +
+#else
+ shmdesc->addr + stuff->offset +
+#endif
+ (stuff->srcY * length));
+ else
+ (*shmFuncs[pDraw->pScreen->myNum]->PutImage)(
+ pDraw, pGC, stuff->depth, stuff->format,
+ stuff->totalWidth, stuff->totalHeight,
+ stuff->srcX, stuff->srcY,
+ stuff->srcWidth, stuff->srcHeight,
+ stuff->dstX, stuff->dstY,
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ tmpImage);
+
+#else
+ shmdesc->addr + stuff->offset);
+#endif
+
+ if (stuff->sendEvent)
+ {
+ xShmCompletionEvent ev;
+
+ ev.type = ShmCompletionCode;
+ ev.drawable = stuff->drawable;
+ ev.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ if (tmpAlloced)
+ DEALLOCATE_LOCAL(tmpImage);
+#endif
+
+ return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(client)
+ register ClientPtr client;
+{
+ register DrawablePtr pDraw;
+ long lenPer, length;
+ Mask plane;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int n;
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ long widthBytesLine,widthBytesLineProto;
+ long lenPerProto,lengthProto;
+ char *tmpImage;
+ int tmpAlloced = 0;
+#endif
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ VERIFY_DRAWABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + stuff->x < 0 ||
+ pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+ pDraw->y + stuff->y < 0 ||
+ pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+ stuff->x + (int)stuff->width >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+ stuff->y + (int)stuff->height >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual(((WindowPtr)pDraw));
+ }
+ else
+ {
+ if (stuff->x < 0 ||
+ stuff->x+(int)stuff->width > pDraw->width ||
+ stuff->y < 0 ||
+ stuff->y+(int)stuff->height > pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+ xgi.type = X_Reply;
+ xgi.length = 0;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(stuff->format == ZPixmap)
+ {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ widthBytesLine = PixmapBytePad(stuff->width, pDraw->depth);
+ length = widthBytesLine * stuff->height;
+ widthBytesLineProto = PixmapBytePadProto(stuff->width, pDraw->depth);
+ lengthProto = widthBytesLineProto * stuff->height;
+#else
+ length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+#endif
+ }
+ else
+ {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ widthBytesLine = PixmapBytePad(stuff->width, 1);
+ lenPer = widthBytesLine * stuff->height;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+
+ widthBytesLineProto = PixmapBytePadProto(stuff->width, 1);
+ lenPerProto = widthBytesLineProto * stuff->height;
+ lengthProto = lenPerProto * Ones(stuff->planeMask &
+ (plane | (plane - 1)));
+#else
+ lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+#endif
+ }
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, lengthProto, client);
+ xgi.size = lengthProto;
+#else
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+ xgi.size = length;
+#endif
+
+ if (length == 0)
+ {
+ /* nothing to do */
+ }
+ else if (stuff->format == ZPixmap)
+ {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /* check for protocol/server padding differences.
+ */
+ if ((widthBytesLine != widthBytesLineProto) ||
+ ((unsigned long)shmdesc->addr + stuff->offset & (sizeof(long)-1)))
+ {
+ /* temp stuff for 64 bit alignment stuff */
+ register char * bufPtr, * protoPtr;
+ register int i;
+
+ if(!(tmpImage = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ tmpAlloced = 1;
+
+ (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, stuff->planeMask,
+ tmpImage);
+
+ /* for 64-bit server, convert image to pad to 32 bits
+ */
+ bzero(shmdesc->addr + stuff->offset,lengthProto);
+
+ for (i=0,bufPtr=tmpImage,protoPtr=shmdesc->addr + stuff->offset;
+ i < stuff->height;
+ bufPtr += widthBytesLine,protoPtr += widthBytesLineProto,
+ i++)
+ bcopy(bufPtr,protoPtr,widthBytesLineProto);
+ }
+ else
+ {
+ (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, stuff->planeMask,
+ shmdesc->addr + stuff->offset);
+ }
+#else
+ (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, stuff->planeMask,
+ shmdesc->addr + stuff->offset);
+#endif
+ }
+ else
+ {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ /* check for protocol/server padding differences.
+ */
+ if ((widthBytesLine != widthBytesLineProto) ||
+ ((unsigned long)shmdesc->addr + stuff->offset &
+ (sizeof(long)-1)))
+ {
+ if(!(tmpImage = (char *) ALLOCATE_LOCAL(length)))
+ return (BadAlloc);
+ tmpAlloced = 1;
+ }
+#endif
+
+ length = stuff->offset;
+ for (; plane; plane >>= 1)
+ {
+ if (stuff->planeMask & plane)
+ {
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ if ((widthBytesLine != widthBytesLineProto) ||
+ ((unsigned long)shmdesc->addr + stuff->offset &
+ (sizeof(long)-1)))
+ {
+ /* get image for each plane.
+ */
+ (*pDraw->pScreen->GetImage)(pDraw,
+ stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, plane,
+ tmpImage);
+
+ /* for 64-bit server, convert image to pad to 32 bits */
+ bzero(shmdesc->addr+length, widthBytesLine);
+ bcopy(tmpImage, shmdesc->addr+length, widthBytesLineProto);
+ /* increment length */
+ length += lenPerProto;
+ }
+ else /* no diff between protocol and server */
+ {
+ (*pDraw->pScreen->GetImage)(pDraw,
+ stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, plane,
+ shmdesc->addr + length);
+ length += lenPer;
+ }
+#else
+ (*pDraw->pScreen->GetImage)(pDraw,
+ stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, plane,
+ shmdesc->addr + length);
+ length += lenPer;
+#endif
+ }
+ }
+ }
+
+ if (client->swapped) {
+ swaps(&xgi.sequenceNumber, n);
+ swapl(&xgi.length, n);
+ swapl(&xgi.visual, n);
+ swapl(&xgi.size, n);
+ }
+ WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+#ifdef INTERNAL_VS_EXTERNAL_PADDING
+ if (tmpAlloced)
+ DEALLOCATE_LOCAL(tmpImage);
+#endif
+
+ return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (pScreen, width, height, depth, addr)
+ ScreenPtr pScreen;
+ int width;
+ int height;
+ int depth;
+ char *addr;
+{
+ register PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth);
+ if (!pPixmap)
+ return NullPixmap;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ /*XXX*/depth, PixmapBytePad(width, depth), (pointer)addr))
+ return NullPixmap;
+ return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(client)
+ register ClientPtr client;
+{
+ PixmapPtr pMap;
+ register DrawablePtr pDraw;
+ DepthPtr pDepth;
+ register int i;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ VERIFY_GEOMETRABLE(pDraw, stuff->drawable, client);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+CreatePmap:
+ VERIFY_SHMSIZE(shmdesc, stuff->offset,
+ PixmapBytePad(stuff->width, stuff->depth) * stuff->height,
+ client);
+ pMap = (*shmFuncs[pDraw->pScreen->myNum]->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ {
+ shmdesc->refcnt++;
+ if (AddResource(stuff->pid, ShmPixType, (pointer)shmdesc))
+ return(client->noClientException);
+ FreeResource(stuff->pid, RT_NONE);
+ }
+ }
+ return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+ return ProcShmPutImage(client);
+ case X_ShmGetImage:
+ return ProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return ProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SShmCompletionEvent(from, to)
+ xShmCompletionEvent *from, *to;
+{
+ to->type = from->type;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->drawable, to->drawable);
+ cpswaps(from->minorEvent, to->minorEvent);
+ to->majorEvent = from->majorEvent;
+ cpswapl(from->shmseg, to->shmseg);
+ cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(client)
+ register ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmAttachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->shmid, n);
+ return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg, n);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmPutImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->totalWidth, n);
+ swaps(&stuff->totalHeight, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ swaps(&stuff->srcWidth, n);
+ swaps(&stuff->srcHeight, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmGetImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->planeMask, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(client)
+ ClientPtr client;
+{
+ register int n;
+ REQUEST(xShmCreatePixmapReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (client)
+ register ClientPtr client;
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ return SProcShmPutImage(client);
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/Xext/sleepuntil.c b/Xext/sleepuntil.c
new file mode 100644
index 000000000..292924ed6
--- /dev/null
+++ b/Xext/sleepuntil.c
@@ -0,0 +1,211 @@
+/*
+ * $Xorg: sleepuntil.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $
+ *
+Copyright 1992, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+/* dixsleep.c - implement millisecond timeouts for X clients */
+
+#include "X.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "windowstr.h"
+#include "dixstruct.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+
+typedef struct _Sertafied {
+ struct _Sertafied *next;
+ TimeStamp revive;
+ ClientPtr pClient;
+ XID id;
+ void (*notifyFunc)();
+ pointer closure;
+} SertafiedRec, *SertafiedPtr;
+
+static SertafiedPtr pPending;
+static RESTYPE SertafiedResType;
+static Bool BlockHandlerRegistered;
+static int SertafiedGeneration;
+static void ClientAwaken();
+static int SertafiedDelete();
+static void SertafiedBlockHandler();
+static void SertafiedWakeupHandler();
+
+ClientSleepUntil (client, revive, notifyFunc, closure)
+ ClientPtr client;
+ TimeStamp *revive;
+ void (*notifyFunc)();
+ pointer closure;
+{
+ SertafiedPtr pRequest, pReq, pPrev;
+
+ if (SertafiedGeneration != serverGeneration)
+ {
+ SertafiedResType = CreateNewResourceType (SertafiedDelete);
+ if (!SertafiedResType)
+ return FALSE;
+ SertafiedGeneration = serverGeneration;
+ BlockHandlerRegistered = FALSE;
+ }
+ pRequest = (SertafiedPtr) xalloc (sizeof (SertafiedRec));
+ if (!pRequest)
+ return FALSE;
+ pRequest->pClient = client;
+ pRequest->revive = *revive;
+ pRequest->id = FakeClientID (client->index);
+ pRequest->closure = closure;
+ if (!BlockHandlerRegistered)
+ {
+ if (!RegisterBlockAndWakeupHandlers (SertafiedBlockHandler,
+ SertafiedWakeupHandler,
+ (pointer) 0))
+ {
+ xfree (pRequest);
+ return FALSE;
+ }
+ BlockHandlerRegistered = TRUE;
+ }
+ pRequest->notifyFunc = 0;
+ if (!AddResource (pRequest->id, SertafiedResType, (pointer) pRequest))
+ return FALSE;
+ if (!notifyFunc)
+ notifyFunc = ClientAwaken;
+ pRequest->notifyFunc = notifyFunc;
+ /* Insert into time-ordered queue, with earliest activation time coming first. */
+ pPrev = 0;
+ for (pReq = pPending; pReq; pReq = pReq->next)
+ {
+ if (CompareTimeStamps (pReq->revive, *revive) == LATER)
+ break;
+ pPrev = pReq;
+ }
+ if (pPrev)
+ pPrev->next = pRequest;
+ else
+ pPending = pRequest;
+ pRequest->next = pReq;
+ IgnoreClient (client);
+ return TRUE;
+}
+
+static void
+ClientAwaken (client, closure)
+ ClientPtr client;
+ pointer closure;
+{
+ if (!client->clientGone)
+ AttendClient (client);
+}
+
+
+static int
+SertafiedDelete (value, id)
+ pointer value;
+ XID id;
+{
+ SertafiedPtr pRequest = (SertafiedPtr)value;
+ SertafiedPtr pReq, pPrev;
+
+ pPrev = 0;
+ for (pReq = pPending; pReq; pPrev = pReq, pReq = pReq->next)
+ if (pReq == pRequest)
+ {
+ if (pPrev)
+ pPrev->next = pReq->next;
+ else
+ pPending = pReq->next;
+ break;
+ }
+ if (pRequest->notifyFunc)
+ (*pRequest->notifyFunc) (pRequest->pClient, pRequest->closure);
+ xfree (pRequest);
+ return TRUE;
+}
+
+static void
+SertafiedBlockHandler (data, wt, LastSelectMask)
+ pointer data; /* unused */
+ OSTimePtr wt; /* wait time */
+ pointer LastSelectMask;
+{
+ SertafiedPtr pReq, pNext;
+ unsigned long newdelay, olddelay;
+ TimeStamp now;
+
+ if (!pPending)
+ return;
+ now.milliseconds = GetTimeInMillis ();
+ now.months = currentTime.months;
+ if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
+ now.months++;
+ for (pReq = pPending; pReq; pReq = pNext)
+ {
+ pNext = pReq->next;
+ if (CompareTimeStamps (pReq->revive, now) == LATER)
+ break;
+ FreeResource (pReq->id, RT_NONE);
+
+ /* AttendClient() may have been called via the resource delete
+ * function so a client may have input to be processed and so
+ * set delay to 0 to prevent blocking in WaitForSomething().
+ */
+ AdjustWaitForDelay (wt, 0);
+ }
+ pReq = pPending;
+ if (!pReq)
+ return;
+ newdelay = pReq->revive.milliseconds - now.milliseconds;
+ AdjustWaitForDelay (wt, newdelay);
+}
+
+static void
+SertafiedWakeupHandler (data, i, LastSelectMask)
+ pointer data;
+ int i;
+ pointer LastSelectMask;
+{
+ SertafiedPtr pReq, pNext;
+ TimeStamp now;
+
+ now.milliseconds = GetTimeInMillis ();
+ now.months = currentTime.months;
+ if ((int) (now.milliseconds - currentTime.milliseconds) < 0)
+ now.months++;
+ for (pReq = pPending; pReq; pReq = pNext)
+ {
+ pNext = pReq->next;
+ if (CompareTimeStamps (pReq->revive, now) == LATER)
+ break;
+ FreeResource (pReq->id, RT_NONE);
+ }
+ if (!pPending)
+ {
+ RemoveBlockAndWakeupHandlers (SertafiedBlockHandler,
+ SertafiedWakeupHandler,
+ (pointer) 0);
+ BlockHandlerRegistered = FALSE;
+ }
+}
diff --git a/Xext/sync.c b/Xext/sync.c
new file mode 100644
index 000000000..8274d2522
--- /dev/null
+++ b/Xext/sync.c
@@ -0,0 +1,2322 @@
+/* $Xorg: sync.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
+/*
+
+Copyright 1991, 1993, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from The Open Group.
+
+
+Copyright 1991, 1993 by Digital Equipment Corporation, Maynard, Massachusetts,
+and Olivetti Research Limited, Cambridge, England.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or Olivetti
+not be used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission. Digital and Olivetti
+make no representations about the suitability of this software
+for any purpose. It is provided "as is" without express or implied warranty.
+
+DIGITAL AND OLIVETTI DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THEY 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.
+
+*/
+
+#define NEED_REPLIES
+#define NEED_EVENTS
+#include <stdio.h>
+#include "X.h"
+#include "Xproto.h"
+#include "Xmd.h"
+#include "misc.h"
+#include "os.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#define _SYNC_SERVER
+#include "sync.h"
+#include "syncstr.h"
+
+/*
+ * Local Global Variables
+ */
+static int SyncReqCode;
+static int SyncEventBase;
+static int SyncErrorBase;
+static RESTYPE RTCounter = 0;
+static RESTYPE RTAwait;
+static RESTYPE RTAlarm;
+static RESTYPE RTAlarmClient;
+static int SyncNumSystemCounters = 0;
+static SyncCounter **SysCounterList = NULL;
+
+#define IsSystemCounter(pCounter) \
+ (pCounter && (pCounter->client == NULL))
+
+/* these are all the alarm attributes that pertain to the alarm's trigger */
+#define XSyncCAAllTrigger \
+ (XSyncCACounter | XSyncCAValueType | XSyncCAValue | XSyncCATestType)
+
+static void SyncComputeBracketValues(
+#if NeedFunctionPrototypes
+ SyncCounter * /* pCounter */,
+ Bool /* startOver */
+#endif
+);
+
+/* Each counter maintains a simple linked list of triggers that are
+ * interested in the counter. The two functions below are used to
+ * delete and add triggers on this list.
+ */
+static void
+SyncDeleteTriggerFromCounter(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncTriggerList *pCur, *pPrev = NULL;
+
+ /* pCounter needs to be stored in pTrigger before calling here. */
+
+ if (!pTrigger->pCounter)
+ return;
+
+ for (pCur = pTrigger->pCounter->pTriglist; pCur; pCur = pCur->next)
+ {
+ if (pCur->pTrigger == pTrigger)
+ {
+ if (pPrev)
+ pPrev->next = pCur->next;
+ else
+ pTrigger->pCounter->pTriglist = pCur->next;
+ xfree(pCur);
+ break;
+ }
+ }
+
+ if (IsSystemCounter(pTrigger->pCounter))
+ SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+}
+
+
+static int
+SyncAddTriggerToCounter(pTrigger)
+ SyncTrigger *pTrigger;
+{
+ SyncTriggerList *pCur;
+
+ if (!pTrigger->pCounter)
+ return Success;
+
+ /* don't do anything if it's already there */
+ for (pCur = pTrigger->pCounter->pTriglist; pCur; pCur = pCur->next)
+ {
+ if (pCur->pTrigger == pTrigger)
+ return Success;
+ }
+
+ if (!(pCur = (SyncTriggerList *)xalloc(sizeof(SyncTriggerList))))
+ return BadAlloc;
+
+ pCur->pTrigger = pTrigger;
+ pCur->next = pTrigger->pCounter->pTriglist;
+ pTrigger->pCounter->pTriglist = pCur;
+
+ if (IsSystemCounter(pTrigger->pCounter))
+ SyncComputeBracketValues(pTrigger->pCounter, /*startOver*/ TRUE);
+
+ return Success;
+}
+
+
+/* Below are four possible functions that can be plugged into
+ * pTrigger->CheckTrigger, corresponding to the four possible
+ * test-types. These functions are called after the counter's
+ * value changes but are also passed the old counter value
+ * so they can inspect both the old and new values.
+ * (PositiveTransition and NegativeTransition need to see both
+ * pieces of information.) These functions return the truth value
+ * of the trigger.
+ *
+ * All of them include the condition pTrigger->pCounter == NULL.
+ * This is because the spec says that a trigger with a counter value
+ * of None is always TRUE.
+ */
+
+static Bool
+SyncCheckTriggerPositiveComparison(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ XSyncValueGreaterOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value));
+}
+
+static Bool
+SyncCheckTriggerNegativeComparison(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ XSyncValueLessOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value));
+}
+
+static Bool
+SyncCheckTriggerPositiveTransition(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ (XSyncValueLessThan(oldval, pTrigger->test_value) &&
+ XSyncValueGreaterOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value)));
+}
+
+static Bool
+SyncCheckTriggerNegativeTransition(pTrigger, oldval)
+ SyncTrigger *pTrigger;
+ CARD64 oldval;
+{
+ return (pTrigger->pCounter == NULL ||
+ (XSyncValueGreaterThan(oldval, pTrigger->test_value) &&
+ XSyncValueLessOrEqual(pTrigger->pCounter->value,
+ pTrigger->test_value)));
+}
+
+
+
+static int
+SyncInitTrigger(client, pTrigger, counter, changes)
+ ClientPtr client; /* so we can set errorValue */
+ SyncTrigger *pTrigger;
+ XSyncCounter counter;
+ Mask changes;
+{
+ SyncCounter *pCounter = pTrigger->pCounter;
+ int status;
+ Bool newcounter = FALSE;
+
+ if (changes & XSyncCACounter)
+ {
+ if (counter == None)
+ pCounter = NULL;
+ else if (!(pCounter = (SyncCounter *)SecurityLookupIDByType(
+ client, counter, RTCounter, SecurityReadAccess)))
+ {
+ client->errorValue = counter;
+ return SyncErrorBase + XSyncBadCounter;
+ }
+ if (pCounter != pTrigger->pCounter)
+ { /* new counter for trigger */
+ SyncDeleteTriggerFromCounter(pTrigger);
+ pTrigger->pCounter = pCounter;
+ newcounter = TRUE;
+ }
+ }
+
+ /* if system counter, ask it what the current value is */
+
+ if (IsSystemCounter(pCounter))
+ {
+ (*pCounter->pSysCounterInfo->QueryValue) ((pointer) pCounter,
+ &pCounter->value);
+ }
+
+ if (changes & XSyncCAValueType)
+ {
+ if (pTrigger->value_type != XSyncRelative &&
+ pTrigger->value_type != XSyncAbsolute)
+ {
+ client->errorValue = pTrigger->value_type;
+ return BadValue;
+ }
+ }
+
+ if (changes & XSyncCATestType)
+ {
+ if (pTrigger->test_type != XSyncPositiveTransition &&
+ pTrigger->test_type != XSyncNegativeTransition &&
+ pTrigger->test_type != XSyncPositiveComparison &&
+ pTrigger->test_type != XSyncNegativeComparison)
+ {
+ client->errorValue = pTrigger->test_type;
+ return BadValue;
+ }
+ /* select appropriate Ch